I have a very simple program that I don't know why a crash occurs on exit.
My main function is a simple cout<<"Hello world";
But I've added another cpp file:
system_information.cpp:
system_information::system_information() {
threadid_processid_map[22]=23;
processor_processid_map[128] = { 0L };
processor_threadid_map[128] = { 0L };
}
And the header file looks like:
system_information.h
class system_information{
public:
DWORD processor_processid_map[128];
DWORD processor_threadid_map[128];
unordered_map<DWORD, DWORD> threadid_processid_map;
system_information();
};
And I simply have this file to declare in instance of my class:
parse.cpp:
#include "system_information.h"
system_information sys_info;
My program crashes on exit on crt0at.c at this line:
onexitbegin_new = (_PVFV *) DecodePointer(__onexitbegin);
What am I doing wrong?
I'd say you're slightly confused about what:
processor_processid_map[128] = { 0L };
is actually doing. The fact that you have braces in there seems to indicate you think it will set all values in the array to zero but that is not the case. You can initialise the array that way but assigning to it is a different matter.
What that code is doing is trying to set element number 128 to zero and, since elements are restricted to the range 0..127, what you have there is undefined behaviour.
If you do wish to zero out the entire array, there are a number of ways to do this, including:
// Simple loop.
for (int i = 0; i < sizeof(id_map) / sizeof(*id_map); ++i)
id_map[i] = 0;
// Setting memory.
#include <cstring>
memset(id_map, 0, sizeof(id_map));
// Fill algorithm.
#include <algorithm>
std::fill(id_map, id_map + sizeof(id_map) / sizeof(*id_map), 0);
Related
So first all I'll preface this with: I just started using c++.
I have a structure that I store the pointer to in an unordered_map, setting members' values in the struct pointer as I get them through my process. Then I no longer need them in a map so I transfer then to a vector and loop through them.
Though on the second loop, it outputs my index (1) but the next statement of making a local pointer var for the struct at that index breaks it and the code terminates without any errors. since there are no errors then a try/catch doesn't give me anything either.
// Wanted to create a structure to handle the objects easier instead
// of multiple vectors for each property
struct appData {
std::string id = "";
std::string name = "";
std::string vdf_file = "";
std::string vdf_path = "";
};
// Relevant parts of my main()
int main() {
// Map that stores all the struct pointers
std::unordered_map<std::string, appData*> appDatas;
char memory[sizeof(appData)];
void* p = memory;
// New instance of appData
appData *tempAppData = new(p) appData();
tempAppData->appid = "86901";
// Add tempAppData to map with string key
appDatas["86901"] = tempAppData;
...
std::vector<appData*> unhashed_appDatas;
for (auto const& pair: appDatas) {
unhashed_appDatas.push_back(pair.second);
}
...
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
// Output index to see where it was messing up
std::cout << x << std::endl;
!! // This is where the issue happens on the second loop (see output)
appData *thisAppData = unhashed_appDatas[x];
std::string id = thisAppData->appid;
std::cout << id << std::endl;
/* ...
Do more stuff below
*/
}
...
return 0;
}
Terminal Output:
0 // Initial index of x
86901 // Id of first item
1 // New index of x on second loop before pointer var is created
// Nothing more is printed and execution terminates with no errors
My knowledge of c++ is pretty lacking, started it couple days ago, so the few things within my knowledge I've tried: moving the *thisAppData variable outside of the loop, using a for(var: vector) { ... }, and a while loop. I can assume that the issue lies with the pointer and the local variable when inside the loop.
Any help/input about how I could better approach this or if there's an issue with my code would be appreciated :)
Edit: Changed code to use .size() instead of sizeof() per #Jarod42 answer, though main issue persists
Edit2: Turns out it was my own mess-up, imagine that. 4Am brain wasn't working too well- posted answer regarding what I did incorrectly. Thanks to everyone who helped me
sizeof is the wrong tool here:
for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
// ^^ wrong: give **static** size of the structure
// mainly 3 members (data, capacity, size), so something like `3*sizeof(void*)`
it should be
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
After many hours of trial and error I have determined the issue (aside from doing things in a way I should, which I've since corrected) it was something I messed up on that caused this issue.
TLDR:
Items wouldn't exist that I assumed did and tried to read files with a blank path and parse the contents that didn't exist.
Explaination:
In the first loop, the data I was getting was a list of files from a directory then parsing a json-like file that contained these file names and properties associated with them. Though, the file list contained entries that weren't in this other data file (since I had no check if they existed) so it would break there.
Additionally in the last loop I would get a member from a struct that would be the path of a file to read, but it would be blank (unset) because it didn't exist in data file so std::ifstream file(path); would break it.
I've since implemented checks for each key and value to ensure it will no longer break because of that.
Fixes:
Here are some fixes that were mentioned that I added to the code, which did help it work correctly in the end even if they weren't the main issue that I myself caused:
// Thanks to #EOF:
// No longer "using placement new on a buffer with automatic storage duration"
// (whatever that means haha) and was changed from:
char memory[sizeof(appData)];
void* p = memory;
appData *tempAppData = new(p) appData();
// To:
appData *tempAppData = new appData();
// Thanks to #Jarod42:
// Last for loop limit expression was corrected from:
for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
}
// To:
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
}
// I am still using a map, despite comment noting to just use vectors
// (which I could have, but just would prefer using maps):
std::unordered_map<std::string, appData*> appDatas;
// Instead of doing something like this instead (would have arguably have been easier):
std::vector<std::string> dataKeys = { "1234" };
std::vector<appData*> appDatas = { ... };
auto indx = find(dataKeys.begin(), dataKeys.end(), "1234");
indx = (indx != dataKeys.end() ? indx : -1);
if (indx == -1) continue;
auto dataItem = appDatas[indx];
//
I appreciate everyone's assistance with my code
Here is the chunk of code in question that I've pulled from my program:
#include <vector>
using namespace std;
vector<double> permittingConstructionCosts(56);
static const int PERMITTING_PERIODS = 0;
static const int CONSTRUCTION_PERIODS = 11;
static const double CONSTRUCTION_COSTS = 2169506;
static const double PERMITTING_COSTS = 142085;
static const int PERMITTING_CONSTRUCTION_PERIODS = PERMITTING_PERIODS + CONSTRUCTION_PERIODS;
void calcExpenses // Calculates permitting and construction expenses
(
vector<double>& expense,
double value1,
double value2
)
{
int i;
for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
expense[i] = value1;
}
for (i=PERMITTING_PERIODS + 2; i<expense.size(); i++)
{
if (i < PERMITTING_CONSTRUCTION_PERIODS + 2)
{
expense[i] = value2;
}
}
}
int main()
{
if (PERMITTING_PERIODS != 0)
{
calcExpenses(permittingConstructionCosts, -PERMITTING_COSTS/PERMITTING_PERIODS, -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
}
else
{
calcExpenses(permittingConstructionCosts, 0, -CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
}
return 0;
}
According to ideone (http://ideone.com/LpzUny) the code has a runtime error that returns "time: 0 memory: 3456 signal:11".
I've tried to look for solutions on SO and found the following links:
How can I avoid a warning about division-by-zero in this template code?
How to eliminate "divide by 0" error in template code
However, I don't know how to use templates because I am new to c++ and I'm not sure I need to use them in this case so I have no clue how to adapt those solutions to my particular problem if it's even possible.
I'm pretty sure that the "-PERMITTING_COSTS/PERMITTING_PERIODS" is causing the problem but I thought that simply checking the divisor would solve the problem. This function seems to work for every other value other than 0 but I need to account for the case where PERMITTING_PERIODS = 0 somehow.
I would very much appreciate any help I can get. Thanks in advance!
Edit: I actually do initialize the vector in my program but I forgot to put that in because the size is decided elsewhere in the program. The chunk of code works once I fix that part by putting in a number but my program still has a runtime error when I set PERMITTING_PERIODS to 0 so I guess I have to go bug hunting elsewhere. Thanks for the help!
The problem lies inside the function, which is called by the else statement in the main function:
for (i=0; i<=PERMITTING_PERIODS + 1; i++)
{
expense[i] = value1;
}
Here, PERMITTING_PERIODS is 0, thus you loop from 0 to 2 (inclusive).
However, expense.size() is 0, since your vector is empty. As a result, you are trying to access an empty vector, which causes a segmentation fault.
With that said, print the value of i inside the loop, you should see that you try to access expense[0], but the vector is empty, so it has no first slot (basically it doesn't have any)!!
So replace that with:
expense.push_back(value1);
which will allocate enough space for your values to be pushed into the vector.
The answer given in the cited links, (i.e. "How to eliminate "divide by 0" error in template code") applies equally well here. The other answers were given in the context of templates, but this is completely irrelevant. The sample principle applies equally well with non-template code, too. The key principle is to compute a division, but if the denominator is zero, you want to compute the value of zero instead of the division.
So we want to compute -PERMITTING_COSTS/PERMITTING_PERIODS, but use the value of 0 instead of the division when PERMITTING_PERIODS is 0. Fine:
int main()
{
calcExpenses(permittingConstructionCosts,
(PERMITTING_PERIODS == 0 ? 0: -PERMITTING_COSTS)/
(PERMITTING_PERIODS == 0 ? 1: PERMITTING_PERIODS),
-CONSTRUCTION_COSTS/CONSTRUCTION_PERIODS);
return 0;
}
I just implemented breadth first search in c++ and instead of declaring a vector as bool, I declared it as an int. This lead to a very odd observation. When I used int, the code printed the following:
1
32763
-524268732
Throughout the entire code, I don't provide any such value to variable as the 2nd and 3rd node receive, so I assume that they are just garbage values, but why do garbage values even come up, when I'm initialising the vector to be full of zeroes ??? You may check the code to be that below:
#include <iostream>
#include <queue>
using namespace std;
queue<int> neigh;
vector< vector<int> > graph(3);
vector<int> flag(3, 0);
int main(void)
{
graph[0].push_back(1); graph[0].push_back(2);
graph[1].push_back(0); graph[1].push_back(2);
graph[2].push_back(0); graph[3].push_back(1);
neigh.push(0);
while(!neigh.empty())
{
int cur = neigh.front();
neigh.pop();
flag[cur] = 1;
for(int i = 0, l = graph[cur].size();i < l;i++)
{
if(!flag[graph[cur][i]])
neigh.push(graph[cur][i]);
}
}
for(int i = 0;i < 3;i++)
{
cout << flag[i] << endl;
}
}
Alright, then I changed just a single line of code, line number 7, the one where I declare and initialise the flag vector.
Before:
vector<int> flag(3, 0);
After:
vector<bool> flag(3, false);
And voila! The code started working:
1 //The new output
1
1
So, my question is, what is the problem with the code in the first place ? I believe it may be some kind of error I made, or possibly that its only by chance that my bfs implementation works at all... So, what is the truth, SO? What is my (possible) mistake ?
You are accessing your vector out of bounds here:
graph[3].push_back(1);
At this moment, graph only has three elements. This leads to undefined behaviour.
So I got this code sample that needs fixing. From what I can gather it takes an array, reverses it and then counts all the elements within it. Here is the code.
//-------------------------------------------------------------------
void ReverseTheArray( const short *pArrayStart, const int nArrayByteLength )
{
const short *pArrayEnd = (pArrayStart + nArrayByteLength);
while(pArrayStart != pArrayEnd)
{
short tmp = *pArrayStart;
*pArrayStart = *pArrayEnd;
*pArrayEnd = tmp;
pArrayStart++;
pArrayEnd--;
}
}
//-------------------------------------------------------------------
int CountTheArrayContents( const short *pArrayStart, int nNumEntries )
{
assert(nNumEntries-- > 0);
int nCount = 0;
for(unsigned uArrayIndex = nNumEntries; uArrayIndex >= 0; uArrayIndex--)
{
nCount += pArrayStart[uArrayIndex];
}
return nCount;
}
const short g_nSomeNumbers[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
//-------------------------------------------------------------------
int main()
{
short *pDataArray = new short[10];
memcpy(pDataArray, g_nSomeNumbers, sizeof(g_nSomeNumbers));
ReverseTheArray(pDataArray, 10*sizeof(short));
int nCount = CountTheArrayContents(pDataArray, 10);
printf("Sum total is %0.02f\n", nCount);
return 0;
}
I have ideas of what the problems are but can't seem to figure out a simple solution to the problem, one that doesn't require rewriting the entire code. If anyone can read this and see how the errors can be fixed it would be much appreciated.
I'm going to mention some things that I think are causing problems.
All the parameters and the pArrayEnd variable in the ReversTheArray() function are all const but are trying to be changed within the while loop, which is throwing an error. Should the const's be removed? Is there a reason const's would be used for this?
If the const's are remove a runtime error happens when trying to run the for loop in the CountTheArrayContents() function expressing an unhandled exception and saying "Access violation reading location 0x003DFFFE". Drawing a complete blank on that one.
Again any help on the code would be very much appreciated and I couldn't thank you guys enough.
PS. This is a challenge to create a reverse and accumulate function so I'm looking for a fix for the code and not a removal of the two functions. Thank you
PSS. Thanks to everyone who answered. I'm glad I did this (this being the first problem that I've posted about myself) and you've all been a huge help. I've got to say I've learnt alot.
Adding the actual length in bytes will add too many because pointer arithmetic is defined in terms of units of the size of the type pointed to. That is, pArrayEnd becomes &pDataArray[10 * sizeof(short)] instead of &pDataArray[10]. You don't need to multiply by sizeof(short) when calling the reversal function. Alternatively, you can divide nArrayByteLength by sizeof(short) when calculating the initial value of pArrayEnd.
The second issue is the fact that you only have 10 elements (0..9) allocated, meaning &pDataArray[10] would be one element beyond the array. The reversal function then tries to assign data to this unallocated area of memory, which can cause problems. The function should initialize pArrayEnd as shown, but immediately after, it should decrement pArrayEnd by 1. This way you won't be assigning to memory that might not belong to you. Beware of pArrayStart == pArrayEnd before you decrement pArrayEnd. An alternative test would be to ensure nArrayByteLength != 0.
Another problem is if the array has an even number of elements, and you try to do a reversal. If it does have an even number (like 10), pArrayStart will point to pDataArray[4], pArrayEnd will point to pDataArray[5], and after the data is assigned, pArrayStart++ will make pArrayStart point to pDataArray[5] and pArrayEnd-- point to pDataArray[4]. Then (6,3), (7,2), (8,1), (9,0), ... In other words, pArrayStart will never be equal to pArrayEnd in such a case. Instead, you should ensure that pArrayStart < pArrayEnd.
Hope this helps!
Also, any reason for not using std:: reverse? Just wondering.
Edit
The accumulation function can be rewritten as the following, which will avoid the issue with the assert macro while doing the same thing:
int CountTheArrayContents( const short *pArrayStart, int nNumEntries )
{
int count = 0;
assert(nNumEntries);
while (nNumEntries--)
count += pArrayStart[nNumEntries];
return count;
}
Hopefully count doesn't overflow.
If all you're trying to do is reverse the contents of the array and accumulate the result, std::reverse and std::accumulate will do the trick (per the suggestion by #chris). Here's an example, which maintains the dynamically allocated short*. A better solution would use std::vector or std::array.
#include <algorithm>
#include <numeric>
#include <stdio.h>
#include <memory.h>
const short g_nSomeNumbers[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
int main()
{
short *pDataArray = new short[10];
memcpy(pDataArray, g_nSomeNumbers, sizeof(g_nSomeNumbers));
std::reverse(pDataArray, pDataArray+10);
int nCount = std::accumulate(pDataArray, pDataArray+10, 0);
for( size_t i=0; i<10; ++i )
printf("%d ", pDataArray[i]);
printf("\n");
printf("Sum total is %d\n", nCount);
delete [] pDataArray;
return 0;
}
This prints
9 8 7 6 5 4 3 2 1 0
Sum total is 45
I have the following code compiled in linux terminal (c++ in linux) and am using OpenCv 2.4.3.
However, am getting a segmentation fault in run time and I really have no clue as to why. I have placed differnt cout statements to know if the program processed to the particular stage but in vain. Could you please help me? Please explain me what exactly is this segmentation fault. Am stuck here for a long time.
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
cout<<"check"<<flush;
Mat src,src_gray,dst;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
char* window_name = "sharpness estimate";
int freq,rows,cols =0;
double *estimate,*min = 0;
Point *minLoc,*maxLoc = 0;
src = imread("/home/siddarth/examplescv/erez images/image53.jpg");
if( !src.data )
{
return -1;
}
namedWindow(window_name,CV_WINDOW_AUTOSIZE);
Mat abs_dst;
cvtColor(src,src_gray,CV_RGB2GRAY);
Laplacian(src_gray,dst,ddepth,kernel_size,scale,delta,BORDER_DEFAULT);
convertScaleAbs(dst, abs_dst);
minMaxLoc(dst,min,estimate,minLoc,maxLoc,noArray());
Size s = dst.size();
rows = s.height;
cols = s.width;
cout<<rows<<endl<<cols<<endl;
for(int i=0;i<=rows;i++)
{
for(int j=0;j<=cols;j++)
{
if(dst.at<double>(i,j) >= *estimate-100
&& dst.at<double>(i,j) <= *estimate+100)
{
cout<<freq++;
}
}
}
cout<<"estimate :"<<*estimate<<endl;
cout<<"frequency :"<<freq<<endl;
imshow(window_name,abs_dst);
waitKey(1000);
return 0;
}
The code doesn't cross the first "check" print statement just after the main function declaration. That is the confusing issue. But once I flushed the first print statement, it got executed. I am still facing issues.
Make sure you insert std::endl into cout so that the buffer is flushed. This will probably be why you're not seeing any output.
One immediate issue is that your for loops check the condition with <=, meaning that you're probably going one past the end. But since you're using at, you should have an exception thrown (assuming this Mat type acts like a standard container).
Also, you're creating lots of pointers to pass as some function arguments (for example, double* estimate). This doesn't actually give you a double object though, just a pointer. Unless the function you're passing them to is allocating a double for you (which I hope it's not), you're doing it wrong. You should be doing:
double estimate;
minMaxLoc(/* ... */, &estimate, /* ... */);
You'll need to do that with all of the values you're getting through output parameters.
Another thing to note: Doing int i, j = 0; only initialises j to 0, but not i. You need to do int i = 0, j = 0;.
Okay, I'm going to explain why fixing the initialisers works. I had to look up the definition of minMaxLoc to see what happens. Basically, the function is something like the following:
void setToFive(int* x)
{
if (x) {
*x = 5;
}
}
This function will take a pointer to an int, and then set that int to the value 5. However, if the pointer passed is a null pointer, the value will not be set (otherwise there'll be undefined behaviour because you're derefencing a null pointer). Basically, passing a null pointer says "I don't care about this value so don't give it to me".
Now when you were initialising your pointers, you were doing:
double *estimate, *min = 0;
This only sets min to the null pointer. Since estimate is left uninitialized, you can't rely on its value being null. You need to provide an initialiser for each declarator:
double *estimate = 0, *min = 0;
Thanks to #sftrabbit. The problem was the initialization. instead of
int freq,rows,cols=0;
The change was
int freq=0,rows=0,cols=0;
this removed the segmentation fault. Thanks a lot for your help :).
Since you are in a Linux environment, you can use valgrind to find out exactly where the segmentation fault is happening. Just type valgrind before the name of the program, or the way you execute your program. For example, if you execute your program with the following command:
hello -print
issue the following command instead:
valgrind hello -print
I see you already solved this one, but this may be helpful in the future!