cannot access integers in a vector - c++

The following program is running into segmentation fault and I cannot figure why.
vector<int> *A::B(vector<int> *prefix, vector<int> *projected_tids, int support) {
vector<int> *result = NULL;
for(it_vec it = projected_tids->begin(); it != projected_tids->end(); ++it) {
if(projected_tids == NULL) {
cout<<"NULL";
} else {
cout<<"abc"<<endl;
cout<<&projected_tids<<"address"<<endl;
}
cout<<"here"<<projected_tids->size()<<" "<<prefix->size()<<endl;
cout<<"iteration: "<<projected_tids->at(1)<<endl; //seg fault here
map<int, bool> *transaction = (*processed_input)[*it]; //seg fault here as well, because of *it
bool found = true;
//some more code
}
}
The prompt looks like this:
abc
0x7ffe3894a198address
here16 1
Segmentation fault (core dumped)
GDB is also confusing, might be because I am using C++ after a long time, but I cannot figure why? Below is GDB output:
(gdb) print projected_tids == (void *)0
$14 = false
(gdb) print *(projected_tids._M_impl._M_start)#1
Cannot access memory at address 0x0
(gdb) print *(projected_tids._M_impl._M_start)#3
Cannot access memory at address 0x0
(gdb) print projected_tids
$15 = (std::vector<int, std::allocator<int> > *) 0x60e000
The allocation of pointer to vector is done as in the calling class:
vector<int> *projected_tids = new vector<int>();
Please let me know if any more information is needed.

OK So a number of things going wrong. Concentrating on the question, it looks like:
projected_tids is not NULL (as you're done your check with cout)
Your code then dumps out the address of the projected_tids pointer, (which is on the stack), not the address of the vector. There's nothing wrong with that, but will be a bit misleading.
It reports that projected_tids contains 16 elements
It then seg faults (i.e. invalid use of pointer) when you look at the 2nd item (at(1) use a 0-index). This is the big hint that something is a bit wrong.
It looks like projected_tids is not a valid vector. Whatever is passing the data into your A::B method is passing in a bad pointer somehow. Perhaps uninitialised? You say it's allocated, but maybe it was deleted then?
A few other bits
As mentioned, you're using projected_tids before checking if it was NULL
What's the processed_input pointer all about? There's no reference to it anywhere
Why not use references? They're safer and just as performant as passing pointers.

You already call a member function on a pointer-to-object without checking for NULL first:
for(it_vec it = projected_tids->begin(); it != projected_tids->end(); ++it) {
^^^^^^^^^^^^^^^^^^^^^^^
unconditional call to member function
if(projected_tids == NULL) {
^^^^^^^^^^^^^^^^^^^^^^^^^^
Only here you test for NULL or not
So the logic in your program is flawed (big time) and anything might happen.
Also you cannot use ->at(1) without checking that the size is at least 2. In your example the size of the vector is 0.
As an aside: why don't you pass the vectors in by reference?

The logic does not seem correct.
if(projected_tids == NULL) {
cout<<"NULL";
} else {
you check for null.If it is null, you print null and then go ahead and dereference it.
cout<<"iteration: "<<projected_tids->at(1)<<endl;
If it is NULL, donot dereference it.

Related

c++ segmentation fault on valid pointer

I am getting a segmentation fault on a call on a member function of a pointer. However, it looks like the pointer is valid as the call to another member just before works fine and the debugger shows that the pointer seems to point somewhere. It also shows all the members of the pointer with valid values
m_callListener #0x1fe2b68 CallListener
m_requests 10 long
m_waiting_r 3 long
void Handler::onCall()
{
if (m_state == Waiting)
{
m_callListener->logWaiting();
}
m_callListener->onCall(); // <--SEGMENTATION FAULT HERE
}
void CallListener::logWaiting() { m_waiting_r += 1; }
I only know segmentation fault errors form de-referencing null pointers, accessing an array out of its bounds or trying to write access const values and googling brings up mostly answers related to those. But it if I am not mistaken, I have a valid pointer and there is no array involved and no constant values. What could be the reason for the segfault here? any hints how I can approach debugging this? I am fairly clueless where to even start and what to post here to make things clearer

Segmentation fault with struct array using calloc

I have a struct:
typedef struct{
int *issueTypeCount;
}issueTypeTracker;
I've declared a variable of type issueTypeTracker:
issueTypeTracker *typeTracker;
I've allocated necessary memory:
typeTracker = (issueTypeTracker*) malloc(sizeof(issueTypeTracker) * issueTypeList.count());
typeTracker->issueTypeCount = (int*) calloc(65536,sizeof(int));
And then when I try to do something with it, I get a segmentation fault
while(qry.next()){ //while there are records in the query
for(j=0;j<locationList.count();j++){ // no problem
if(qry.value(1) == locationList[j]){ //no problem
for(i=0;i<issueTypeList.count();i++){ //no problem
typeTracker[j].issueTypeCount[i]++; //seg fault as soon as we hit this line
}
}
}
}
I figured it would be a problem with the way i've allocated memory, but as far as I'm aware i've done it correctly. I've tried the solutions proposed in this question, however it still did not work.
I've tried replacing typeTracker->issueTypeCount = (int*) calloc(65536,sizeof(int)); with:
for(j=0;j<issueTypeList.count();j++){
typeTracker[j].issueTypeCount = (int*) calloc(65536,sizeof(int));
}
But I still get the same issue. This happens with any value of j or i, even zero.
This is a lot more trouble than it's worth and a poor implementation of what I'm trying to do anyway, so I'm probably going to scrap this entire thing and just use a multidimensional array. Even so, I'd like to know why this doesn't work, so in the future I don't have trouble when i'm faced with a similar scenario.
You have several issues. Firstly, you're not checking your allocations for success, so any of your pointers could be NULL/nullptr.
Secondly,
typeTracker->issueTypeCount = (int*) calloc(65536,sizeof(int));
is equivalent to
typeTracker[0].issueTypeCount = (int*) calloc(65536,sizeof(int));
so, you initialized the issueTypeCount member for only the first issueTypeTracker in your array. For the other issueTypeList.count() - 1 elements in the array, the pointer is uninitialized.
Therefore this line:
typeTracker[j].issueTypeCount[i]++; //seg fault as soon as we hit this line
will invoke UB for any j>0. Obviously if your allocation failed, you have UB for j==0 as well.

Crashing with a null pointer de-reference, why?

I was reading Moai source code, and I became curious about why this should cause a crash (or not...)
I do not really understood that snippet.
In file A:
#define UNUSED(p) (( void )p)
In file B:
//----------------------------------------------------------------//
/** #name crash
#text Crashes Moai with a null pointer dereference.
#out nil
*/
int MOAISim::_crash ( lua_State* L ) {
UNUSED(L);
int *p = NULL;
(*p) = 0;
return 0;
}
EDIT:
I think part of what I was not understanding is what "deference" means. So if you put that in your answers it would be awesome.
The crash is caused by the dereference of the null pointer:
(*p) = 0; // <--- Crash
Also as pointed out in the comments, the UNUSED macros is only there to suppress the "unused parameter" warning that most compilers will give.
It is usually also possible to prevent the warning by, simply, not specifying the variable name as follows:
int MOAISim::_crash ( lua_State* )
{
int *p = NULL;
(*p) = 0;
return 0;
}
It's also worth bearing in mind that the above is not a guaranteed crash. On one of the 32-bit consoles de-referencing a null pointer actually resulted in the number "3". This did make null dereferences quite hard to find, but generally if you saw a 3 sitting around in a register you could hazard a good guess as to what had just gone wrong.
Dereferencing is essentially asking for the value stored at a given pointer. If the pointer is not valid (that is, pointing at a memory location that the process does not own) then it results in a crash. In Windows this is called an Access Violation (0xC0000005). Under Linux it's a Segmentation Violation, SIGSEGV.
See also
The macro is replaced in the code, so for the compiler the function looks like this:
int MOAISim::_crash ( lua_State* L ) {
(( void )L);
int *p = NULL;
(*p) = 0;
return 0;
}
The (( void )L) line evaluates L and throw away the result. The crash, however, isn't from that line, instead it from the assignment to a NULL address at (*p) = 0.
int *p = NULL;
(*p) = 0;
The second line is an undefined behaviour (dereferencing a nullptr pointer). The fact that is crashes the application on your platform is just one form of undefined behavior (in my opinion good, because you can catch bugs sooner).

Can I create a C++ "zap" function that works on a pointer if it hasn't had memory allocated to it?

I have a zap() function written to deallocate a 1-d array as follows.
void zap(double *(&data))
{
if (data != NULL)
{
delete [] data;
data = NULL;
}
return;
}
I was under the impression that if data != NULL would not try to deallocate memory that had never been allocated, but I think I am mistaken. I am having the following implementation problem.
void fun()
{
int condition = 0;
double *xvec;
double *yvec;
allocate_memory_using_new(yvec); //a function that allocates memory
if (condition == 1) allocate_memory_using_new(xvec);
//some code
//deallocate memory:
zap (yvec);
zap (xvec); //doesn't work
return;
}
The output is the following:
Unhandled exception at 0x6b9e57aa (msvcr100d.dll) in IRASC.exe: 0xC0000005: Access
violation reading location 0xccccccc0.
So I realize it is not a desirable thing to try to call zap when it is obvious that the pointer was never actually used. I am just wondering if there is a way to check the address of the pointer at some point in the zap() function to avoid the exception. Thanks in advance for your help and insight!
Pointers do not get magically initialized to 0, only when they are global or static. You need to do so:
double *xvec = NULL;
double *yvec = NULL;
If you do not, they contain random junk that was left on the stack where they are created. And this junk is most of the time not NULL.
Also, you do not need to check against NULL, as delete is a no-op in that case:
double* xvec = NULL;
delete xvec; // perfectly valid
Further, if you're working with Visual Studio 2010, I recommend to use nullptr instead of NULL.
The values of xvec and yvec point to random numbers, not NULL. I think your allocate_memory function isn't working properly, as it usually would return a pointer to a block of memory, which you would assign to xvec and yvec
In C++ pointers are not initialized automagically to NULL as in other languages (think Java), so the value of xvec (pointer) is undefined, and might or not be NULL when you test.
void fun()
{
double *xvec; // value of xvec undefined, might be 0 or not
// ...
zap (xvec); // if it is not 0, you will try to delete: Undefined Behavior
}
The simple solution is initializing the pointer in the definition double *xvec = 0;. Also, you do not need to test for NULL (or 0) in your zap function, delete will not cause undefined behavior if called on a null pointer:
template <typename T>
inline void zap( T *& p ) {
delete p;
p = 0;
}
I've concluded the the array forms of new and delete qualify as C++ anti-patterns -- they seem reasonable, but in reality almost any and all use of them is basically guaranteed to lead to more grief and problems than usable code.
As such, I'd say that trying to fix your zap is a bit like finding finding a woman who's just been in a fire and gotten 3rd degree burns on at least 85% of her body, and trying to make her better by trimming the fingernail she broke while escaping from the fire.

What can cause a segmentation fault using delete command in C++?

I've written a program that allocates a new object of the class T like this:
T* obj = new T(tid);
where tid is an int
Somewhere else in my code, I'm trying to release the object I've allocated, which is inside a vector, using:
delete(myVec[i]);
and then:
myVec[i] = NULL;
Sometimes it passes without any errors, and in some cases it causes a crash—a segmentation fault.
I've checked before calling delete, and that object is there—I haven't deleted it elsewhere before.
What can cause this crash?
This is my code for inserting objects of the type T to the vector:
_myVec is global
int add() {
int tid = _myVec.size();
T* newT = new T (tid);
if (newT == NULL){
return ERR_CODE;
}
_myVec.push_back(newT);
// _myVec.push_back(new T (tid));
return tid;
}
as it is - the program sometimes crash.
When I replace the push_back line with the commented line, and leave the rest as it is-it works.
but when I replace this code with:
int add() {
int tid = _myVec.size();
if (newT == NULL){
return ERR_CODE;
}
_myVec.push_back(new T (tid));
return tid;
}
it crashes in a different stage...
the newT in the second option is unused, and still - changes the whole process... what is going on here?
Segfaulting mean trying to manipulate a memory location that shouldn't be accessible to the application.
That means that your problem can come from three cases :
Trying to do something with a pointer that points to NULL;
Trying to do something with an uninitialized pointer;
Trying to do something with a pointer that pointed to a now deleted object;
1) is easy to check so I assume you already do it as you nullify the pointers in the vector. If you don't do checks, then do it before the delete call. That will point the case where you are trying to delete an object twice.
3) can't happen if you set NULL to the pointer in the vector.
2) might happen too. In you case, you're using a std::vector, right? Make sure that implicit manipulations of the vector (like reallocation of the internal buffer when not big enough anymore) doesn't corrupt your list.
So, first check that you delete NULL pointers (note that delete(NULL) will not throw! it's the standard and valid behaviour! ) - in your case you shouldn't get to the point to try to delete(NULL).
Then if it never happen, check that you're not having your vector fill with pointers pointing to trash. For example, you should make sure you're familiar with the [Remove-Erase idiom][1].
Now that you added some code I think I can see the problem :
int tid = _myVec.size();
You're using indice as ids.
Now, all depends on the way you delete your objects. (please show it for a more complete answer)
You just set the pointer to NULL.
You remove the pointer from the vector.
If you only do 1), then it should be safe (if you don't bother having a vector that grows and never get released and ids aren't re-used).
If you do 2. then this is all wrong : each time you remove an object from a vector, all the object still contains after the removed object position will be lowered by one. Making any stored id/index invalid.
Make sure you're coherent on this point, it is certainly a source of errors.
that segmentation fault is most probably and memory access violation. Some reasons
1) object already deallocated. be sure you set that array position on NULL after delete
2) you are out of array bounds
3) if you access that array from multiple threads make sure you are synchronizing correctly
If you're completely certain that pointer points to a valid object, and that the act of deleting it causes the crash, then you have heap corruption.
You should try using a ptr_vector, unlike your code, it's guaranteed to be exception-safe.
Hint: if you write delete, you're doing it wrong
You can't be sure that the object is still valid: the memory that was occupied by the object is not necessarily cleaned, and therefore, you can be seeing something that appears to be your object but it is not anymore.
You can use a mark in order to be sure that the object is still alive, and delete that mark in the destructor.
class A {
public:
static const unsigned int Inactive;
static const unsigned int Active;
A();
~A();
/* more things ...*/
private:
unsigned int mark;
};
const unsigned int A::Inactive = 0xDEADBEEF;
const unsigned int A::Active = 0x11BEBEEF;
A::A() : mark( Active )
{}
A::~A()
{
mark = Inactive;
}
This way, checking the first 4 bytes in your object you can easily verify whether your object has finished its live or not.