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
Related
I've met a situation that I think it is undefined behavior: there is a structure that has some member and one of them is a void pointer (it is not my code and it is not public, I suppose the void pointer is to make it more generic). At some point to this pointer is allocated some char memory:
void fooTest(ThatStructure * someStrPtr) {
try {
someStrPtr->voidPointer = new char[someStrPtr->someVal + someStrPtr->someOtherVal];
} catch (std::bad_alloc$ ba) {
std::cerr << ba.what << std::endl;
}
// ...
and at some point it crashes at the allocation part (operator new) with Segmentation fault (a few times it works, there are more calls of this function, more cases). I've seen this in debug.
I also know that on Windows (my machine is using Linux) there is also a Segmentation fault at the beginning (I suppose that in the first call of the function that allocates the memory).
More, if I added a print of the values :
std::cout << someStrPtr->someVal << " " << someStrPtr->someOtherVal << std::endl;
before the try block, it runs through the end. This print I've done to see if there is some other problem regarding the structure pointer, but the values are printed and not 0 or negative.
I've seen these topics: topic1, topic2, topic3 and I am thinking that there is some UB linked to the void pointer. Can anyone help me in pointing the issue here so I can solve it, thanks?
No, that in itself is not undefined behavior. In general, when code "crashes at the allocation part", it's because something earlier messed up the heap, typically by writing past one end of an allocated block or releasing the same block more than once. In short: the bug isn't in this code.
A void pointer is a perfectly fine thing to do in C/C++ and you can usually cast from/to other types
When you get a seg-fault while initialization, this means some of the used parameters are themselves invalid or so:
Is someStrPtr valid?
is someStrPtr->someVal and someStrPtr->someotherVal valid?
Are the values printed is what you were expecting?
Also if this is a multuthreaded application, make sure that no other thread is accessing those variables (especially between your print and initialization statement). This is what is really difficult to catch
This question already has answers here:
C++ SegFault when dereferencing a pointer for cout
(5 answers)
Closed 6 years ago.
I get segmentation fault when a structure member points to another structure. In details, my new structure is
typedef struct _sock_t{
ir_socket_t *_socket;
bool flag;
extern_class obj;
double *vect;
};
while the structure I want to point to is ir_socket_t socket;. In main(), if I do something like
_sock_t *_sock ;
_sock->_socket = &socket;
I then get segmentation fault. However,
_sock_t _sock ;
_sock._socket = &socket;
works fine. What is wrong about the first approach.
P.S. Note that ir_socket_t is C not C++ structure.
UPDATE:
If I also consider a C++ class object as new a structure member, then I still get segmentation fault at
int n(4);
_sock->obj.resize(4); // here segmentation fault
while there is no problem with the latter approach (no pointer). This happens even if I do _sock_t *_sock = (_sock_t *)malloc(sizeof(_sock_t));; using #Bathshebba answer.
What could be the issue please?
Note that _sock->vect= new double[n] works fine.
Note also that _sock = new _sock_t; works instead fine.
That's hardly surprising. In writing _sock_t *_sock all you've done is declare a pointer.
But it doesn't point to anything. The behaviour on dereferencing it (in your case via the pointer to member operator ->) is undefined.
You need to point it at allocated memory. Use malloc for this in C, and new in C++. Don't forget to call free and delete respectively once you're done with the pointer, else you'll leak memory.
Finally, (acknowledge #Karthick), it appears you're using a C++ compiler to compile C code: in C you'd need to write struct _sock_t *_sock;.
This question already has answers here:
What happens in OS when we dereference a NULL pointer in C?
(5 answers)
Closed 6 years ago.
#include <iostream>
int main()
{
int *ptr = NULL;
// It does not crash
*ptr; --------> Point-1
//But this statment crashed
std::cout<<"Null:"<<*ptr<<"\n"; ------> Point-2
return 0;
}
In the above code when i comment "Point-2" the code is not crashed.
But when i un-comment the "Point-2" it is crashed.
Since ptr is NULL ideally the Point-1 should also crash. Please corret me if i am wrong.
Can someone explain me why the code not crashed when i simply dereffernece the pointer ?
Dereferencing a null pointer is undefined behavior. Undefined behavior is not equal to error. Anything may happen if you triggered undefined behavior. If you are asking the other way:
Why is undefined behavior not causing an error instead of giving us strange behavior?
It may be due to many reason. One reason is performance. For example, in the implementation of std::vector (at least in MSVC), there is no check if the index is out of range in Release Mode. You can try to do this:
std::vector<int> v(4);
v[4]=0;
It will compile and run. You may got strange behavior or you may not. However, in Debug mode it will throw exception at run-time. MSVC does the check in Debug Mode because performance is not important in Debug Mode. But it does not in Release Mode because performance matters.
The same applies for dereferencing a null pointer. You can image that the code of dereferencing will be put in a wrapper like this:
//Imaginary code
T& dereference(T* ptr){
if(ptr==nullptr){
throw;
}
return *ptr;
}
This part: if(ptr==nullptr){throw;} will slow the dereferencing process of every pointer in the context which is not desirable.
However, it may be done like this:
//Imaginary code
T& dereference(T* ptr){
#ifdef DEBUG
if(ptr==nullptr){
throw;
}
#endif
return *ptr;
}
I think you got the idea now.
In point 2 you try to display contents of 0x0 address, which generates access violation error.
In point 1, you do nothing with it, so the program doesn't have to access memory described by this pointer. This generates no acces violation error.
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.
I'm getting an access violation on a char array I just created using new.
DispatchCommand(char* cmdStr)
{
// Dispatch
for(int i = 0; i < sizeof(_lpCommands); i++)
{
const int len = strlen(_lpCommands[i].szCommand);
char* cmdblip = new char[len + 1];
memcpy(&cmdblip, cmdStr, len);
cmdblip[len] = '\0'; // Access Violation
if(strcmp(cmdblip, _lpCommands[i].szCommand) == 0)
{
if(strlen(cmdStr) > strlen(_lpCommands[i].szCommand))
(*_lpCommands[i].cbCallback)(&cmdStr[strlen(_lpCommands[i].szCommand)]);
else
(*_lpCommands[i].cbCallback)("");
delete cmdblip;
return;
}
delete cmdblip;
}
// Error and return
*Out::ServerInfo<<"Command not found!"<<ENDL;
}
_lpCommands is an array of Command structures:
struct Command
{
char* szCommand;
CommandCallback cbCallback;
};
The produced error message is:
Unhandled exception at 0x012219cf in Program.exe: 0xC0000005: Access
violation writing location 0x66647366.
This was a rewrite of similar code which was using memcmp, which ended up giving me an access violation as well without be doing a memcpy.
What gives?
Don't pass &cmdblip to memcpy. You should pass a pointer to the destination buffer, not a pointer to that pointer. Pass cmdblip instead.
Edit: I agree that in general, std::string should be used in C++. Still, the technical reason this code crashes is that memcpy corrupts the cmdblip pointer, making it point on a memory location that is actually made of the first 4 bytes of the copied string. Then, cmdblip[len] results in a memory location that is not within the allocated buffer (or any other legally allocated buffer), hence the crash. So, if you want to write better code, use C++ classes. And if you want to understand why the given code crashed, consider the above.
The only possible helpful answer to this question is "Use std::string". The specific problem you are having now will simply re-occur, or an identical one, every time you modify this function or write another like it. The only way to solve the problem in the general case is to move to a class-based solution, which is kindly provided for you as Standard. For example, your current code is exception unsafe, on top of whatever is giving you an access violation, not to mention that it's unreadable and begging for a number of other errors, such as off-by-one, not properly NULL terminating, double deletes, and memory leaks. Oh, and UB because you delete what you new[].