Whether code is read from top to bottom - c

I am creating a program in c which is based on a linked list, where every node (of struct) holds an integer and a pointer to the next node.
I use dynamic allocation (malloc) and deallocation (free) as new nodes are added and old nodes are deleted.
when a node is deleted a function named delete is called.
I discovered that the program crashes sometimes when this delete-function is called and I KNOW that its something with the pointers in the method but I dont know WHERE in the code (row number) and WHY this happends.
I am used to high-level languages such as Java and I am used to encircle the problem by putting print-syntax at certain places in the method just to reveal WHERE it crashes.
I thought I could do the same with c and with pointer because to my knowledge I beleive the code is read from top to bottom that is 1, 2, 3, 4, and so on. (maybe interrupt handlers behave another way?)
So in this function named delete I have gone so far by putting this printf() at the very beginning of the delete-function - and all the same the program crashes.
So my Question - is it really possible that its some syntax in the delete-function (when I loop pointers for instance) that causes the crash WHEN not even the printf() is printing?
Am I wrong when I believe that the program is executed from to to bottom - that is 1, 2, 3 ....
You can se my printf-function in the very beginning of delete-function
And by the way - how could I solve this problem when I get this cryptic crash message from windows? See the bitmap!!
Greatful for answers!!!
int delete(int data) {
printf("IN THE BEGINNING OF DELETE!!!");
int result = 0;
if (queueref.last != NULL) {
node *curr_ptr;
node *prev_ptr;
node *temp_ptr;
if (queueref.first->data == data) {
temp_ptr = queueref.first;
queueref.first = queueref.first->next;
destroy_node(temp_ptr);
result = 1;
if (queueref.first == NULL) {
queueref.last = NULL;
puts("queue is now empty!!!");
}
} else {
prev_ptr = queueref.first;
curr_ptr = queueref.first->next;
printf("prev_ptr: %d\n", prev_ptr);
printf("curr_ptr: %d\n", curr_ptr);
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next;
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
}
}
}
return result;
}

Common mistake, here's the deal. This
printf("IN THE BEGINNING OF DELETE!!!");
needs to be
printf("IN THE BEGINNING OF DELETE!!!\n");
^^ note the newline
The reason is because stdio does not flush stdout until it sees a newline. If you add that newline, you should see the printf when the code enters the function. Without it, the program could crash, the stdout buffer would not have been flushed and would not see the printf.

Your code seems to have lots of implementation flaws. As a general advice I would recommend using some standard well-tested queue support library and static code analyzers (in this case you would even find dynamic analyzer valgrind very helpful, I guess).
For example, if implementation of destroy_node(ptr) is equivalent to free(ptr), then your code suffers from referencing destroyed data (or ,in other words, garbage) in this code snippet:
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next; //<- curr_ptr is still in stack
//or register, but curr->next
//is garbage
// what if curr_ptr is first node? did you forget to update queueref.first?
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
// if you you need to destroy only one node - you can leave the loop here with break;
}
curr_ptr = curr_ptr->next; /// assigning garbage again if node is found
prev_ptr = prev_ptr->next;
The reason why using destroyed data can work in * most * (if I can say that, basically this is unpredictable) cases is that the chances that this memory can be reused by other part of program for dynamically allocated data can vary on timings and code flow.
PS
Regarding cryptic messages in the Windows box - when program crashes OS basically generates crashdump and prints registers (and dumps some relevant memory parts). Registers and memory dumps can show the place of crash and immediate register/stack values but you have to now memory map and assembler output to understand it. Crashdump can be loaded to debugger (WinDbg) together with unstripped binary to check stactrace and values of local variables at the moment of crash. All these I described very very briefly, you could find tons of books / guides searching for "windows crash or crashdump analysis"

Related

C: Segmentation fault: GDB: <error reading variable>

I have a function shortestPath() that is a modified implementation of Dijkstra's algorithm for use with a board game AI I am working on for my comp2 class. I have trawled through the website and using gdb and valgrind I know exactly where the segfault happens (actually knew that a few hours ago), but can't figure out what undefined behaviour or logic error is causing the problem.
The function in which the problem occurs is called around 10x and works as expected until it segfaults with GDB:
"error reading variable: cannot access memory"
and valgrind:
"Invalid read of size 8"
Normally that would be enough, but I can't work this one out. Also any general advise and tips are appreciated... thanks!
GDB: https://gist.github.com/mckayryan/b8d1e9cdcc58dd1627ea
Valgrind: https://gist.github.com/mckayryan/8495963f6e62a51a734f
Here is the function in which the segfault occurs:
static void processBuffer (GameView currentView, Link pQ, int *pQLen,
LocationID *buffer, int bufferLen, Link prev,
LocationID cur)
{
//printLinkIndex("prev", prev, NUM_MAP_LOCATIONS);
// adds newly retrieved buffer Locations to queue adding link types
appendLocationsToQueue(currentView, pQ, pQLen, buffer, bufferLen, cur);
// calculates distance of new locations and updates prev when needed
updatePrev(currentView, pQ, pQLen, prev, cur); <--- this line here
qsort((void *) pQ, *pQLen, sizeof(link), (compfn)cmpDist);
// qsort sanity check
int i, qsortErr = 0;
for (i = 0; i < *pQLen-1; i++)
if (pQ[i].dist > pQ[i+1].dist) qsortErr = 1;
if (qsortErr) {
fprintf(stderr, "loadToPQ: qsort did not sort succesfully");
abort();
}
}
and the function whereby after it is called everything falls apart:
static void appendLocationsToQueue (GameView currentView, Link pQ,
int *pQLen, LocationID *buffer,
int bufferLen, LocationID cur)
{
int i, c, conns;
TransportID type[MAX_TRANSPORT] = { NONE };
for (i = 0; i < bufferLen; i++) {
// get connection information (up to 3 possible)
conns = connections(currentView->gameMap, cur, buffer[i], type);
for (c = 0; c < conns; c++) {
pQ[*pQLen].loc = buffer[i];
pQ[(*pQLen)++].type = type[c];
}
}
}
So I thought that a pointer had been overridden to the wrong address, but after a lot of printing in GDB that doesn't seem to be the case. I also rotated through making reads/writes to the variables in question to see which trigger the fault and they all do after appendLocationsToQueue(), but not before (or at the end of that function for that matter).
Here is the rest of the relevant code:
shortestPath():
Link shortestPath (GameView currentView, LocationID from, LocationID to, PlayerID player, int road, int rail, int boat)
{
if (!RAIL_MOVE) rail = 0;
// index of locations that have been visited
int visited[NUM_MAP_LOCATIONS] = { 0 };
// current shortest distance from the source
// the previous node for current known shortest path
Link prev;
if(!(prev = malloc(NUM_MAP_LOCATIONS*sizeof(link))))
fprintf(stderr, "GameView.c: shortestPath: malloc failure (prev)");
int i;
// intialise link data structure
for (i = 0; i < NUM_MAP_LOCATIONS; i++) {
prev[i].loc = NOWHERE;
prev[i].type = NONE;
if (i != from) prev[i].dist = INF;
else prev[i].dist = LAST;
}
LocationID *buffer, cur;
// a priority queue that dictates the order LocationID's are checked
Link pQ;
int bufferLen, pQLen = 0;
if (!(pQ = malloc(MAX_QUEUE*sizeof(link))))
fprintf(stderr, "GameView.c: shortestPath: malloc failure (pQ)");
// load initial location into queue
pQ[pQLen++].loc = from;
while (!visited[to]) {
// remove first item from queue into cur
shift(pQ, &pQLen, &cur);
if (visited[cur]) continue;
// freeing malloc from connectedLocations()
if (cur != from) free(buffer);
// find all locations connected to
buffer = connectedLocations(currentView, &bufferLen, cur,
player, currentView->roundNum, road,
rail, boat);
// mark current node as visited
visited[cur] = VISITED;
// locations from buffer are used to update priority queue (pQ)
// and distance information in prev
processBuffer(currentView, pQ, &pQLen, buffer, bufferLen, prev,
cur);
}
free(buffer);
free(pQ);
return prev;
}
The fact that all your parameters look good before this line:
appendLocationsToQueue(currentView, pQ, pQLen, buffer, bufferLen, cur);
and become unavailable after it tells me that you've stepped on (wrote 0x7fff00000000 to) the $rbp register (all local variables and parameters are relative to $rbp when building without optimization).
You can confirm this in GDB with print $rbp before and after call to appendLocationsToQueue ($rbp is supposed to always have the same value inside a given function, but will have changed).
Assuming this is true, there are only a few ways this could happen, and the most likely way is a stack buffer overflow in appendLocationsToQueue (or something it calls).
You should be able to use Address Sanitizer (g++ -fsanitize=address ...) to find this bug fairly easily.
It's also fairly easy to find the overflow in GDB: step into appendLocationsToQueue, and do watch -l *(char**)$rbp, continue. The watchpoint should fire when your code overwrites the $rbp save location.

C Programming - fprintf and printf in while cicle doesn't work

I'm getting a strange problem with a while cicle inside of a function.
I have to look for the extreme vertices of a .ply model. All the data is stored in a linked list. When I'm done creating the list, I call the findExtremeVertex function, that modifies 6 global variables (leftVertex, rightVertex, downwardVertex, upwardVertex, backVertex and frontVertex).
To see if the values are right (the models I use are a bit too big to control every single line to find the maximum of every vertex) I decided to print every change in the max-min values but, when I try to print them in a file, the file is empty. Why is that? Also, when I saw that the file was empty, I tried to print something directly in the console but that didn't work either.
Here's the code of the funcion:
void findExtremeVertex(Vertex *vertex){
FILE *modelInfoFile;
int i = 0;
///Giving data to direction-vertices pointers
leftVertex = malloc(sizeof(Vertex));
rightVertex = malloc(sizeof(Vertex));
upwardVertex = malloc(sizeof(Vertex));
downwardVertex = malloc(sizeof(Vertex));
frontVertex = malloc(sizeof(Vertex));
backVertex = malloc(sizeof(Vertex));
///Giving the direction-vertices the values of the parameter
leftVertex = vertex;
rightVertex = vertex;
upwardVertex = vertex;
downwardVertex = vertex;
frontVertex = vertex;
backVertex = vertex;
///Opening file
modelInfoFile = fopen(us2, "w");
if(modelInfoFile == NULL){
printf("Error in file opening. Exiting.");
exit(EXIT_FAILURE);
}
///Scrolling the list
while(vertex->prev != NULL){
vertex = vertex->prev;
///If the given element of the list is more to the right than the global variable,
///I assign the values of the element to the global variable
if(vertex->vertexCoordinates.x > rightVertex->vertexCoordinates.x){
rightVertex = vertex;
}
/**
I'm omitting the other if constructs because are basically
the same, but the syntax is correct
**/
///Printing in file the cycle information
fprintf(modelInfoFile, "********** CYCLE %d **********\n\n", i);
fprintf(modelInfoFile, "Vertex sx\n");
fprintf(modelInfoFile, "%1.4f %1.4f %1.4f %1.4f %1.4f %1.4f\n\n", leftVertex->vertexCoordinates.x,
leftVertex->vertexCoordinates.y,
leftVertex->vertexCoordinates.z,
leftVertex->vertexNormals.x,
leftVertex->vertexNormals.y,
leftVertex->vertexNormals.z);
/**
Again, I'm omitting some repetitions but the syntax is correct
**/
}
}
I call this function in another function, but there's no segmentation fault signal, the compiler doesn't tell me anything, the program doesn't crash. I have no clue of the error, except from the fact that the file where I print the infos about the cycles is empty. What am I doing wrong?
There are many problems in your code.
You malloc() 6 variables and never use any of them, and you don't check if malloc() succeeded.
You never call fclose() or fflush() so maybe you are seeing the file before the data is flushed to the disk.
You reassign all the *Vertex (except for rightVertex) variables after they are malloc()ed to the same pointer vertex which means
You are causing a memory leak.
You are using 6 variables for a single pointer.
All the *Vertex variables are not declared inside the function which means that they are in the global scope, that is very likely a bad design choice. Given the code you posted it's not possible to tell whether or not global variables are the right choice, but 99% of the time they are a bad choice and there is a much more elegant and safe way to do things.
The bold point above is likely the reason why your program is behaving as it is.
The code
leftVertex = vertex;
rightVertex = vertex;
upwardVertex = vertex;
downwardVertex = vertex;
frontVertex = vertex;
backVertex = vertex;
sets the pointer value but not the actual value. You malloc space, get a pointer to that space, and then throw that pointer away setting it to the pointer of virtex.
Do you mean to use
*leftVertex = *vertex;
*rightVertex = *vertex;
*upwardVertex = *vertex;
*downwardVertex = *vertex;
*frontVertex = *vertex;
*backVertex = *vertex;
///Scrolling the list
while(vertex->prev != NULL){
vertex = vertex->prev;
And what happens if vertex is NULL after this?
You're checking if it's NULL, then changing it's value such that it can become NULL.
///Opening file
if(modelInfoFile == NULL){
printf("Error in file opening. Exiting.");
exit(EXIT_FAILURE);
}
I don't see you opening file.
if((modelInfoFile=fopen(filename,"w")) == NULL){
Should work.
EDIT
In you while loop you change -
vertex = vertex->prev;
But in fprintf you store in file in value of leftVertex->vertexCoordinates.x
So how do you expect to print inside file correctly.

How do we handle freeing a BST when malloc fails in the middle of our recursive build?

I've done some looking around and can't really find a good source that even addresses the idea.
First: It's well known that we should always check if malloc() and realloc() return null. This is commonly done in some way similar to:
Word* temp;
if ((temp = (Word*)malloc(sizeof(Word))) == NULL) {
fprintf(stderr, "unable to malloc for node.\n");
exit(EXIT_FAILURE);
}
However, we also generally build binary search trees in a recursive manner, like so:
void buildTree(Word** tree, const char* input) {
//See if we have found the spot to insert the node.
//Do this by checking for NULL
if (!(*tree)) {
*tree = createNode(input);
return;
}
//else, move left or right accordingly.
if (strcmp(input, (*tree)->data) < 0)
buildTree(&(*tree)->left, input);
else
buildTree(&(*tree)->right, input);
return;
}
So, what do we do if we start working with massive data sets and malloc() fails to allocate memory in the middle of that recursive buildTree function? I've tried a number of things from keeping track of a "global error" flag and a "global head" node pointer and it just seems to be more and more messy the more I try. Examples working with building BSTs rarely seem to give any thought to malloc() failing, so they aren't really helpful in this regard.
I can logically see that one answer is "Don't use recursion and return the head of the tree each time." and while I can see why that would work, I'm an undergraduate TA and one of the things we use BSTs to teach is recursion. So, saying "don't use recursion" to my students when we are TEACHING recursion would be self-defeating.
Any thoughts, suggestions, or links would be greatly appreciated.
We usually use a return error and let the caller free it, after all it could very well free other non critical resources and try to insert the node again.
#define BUILD_OK 0
#define BUILD_FAILED 1
int buildTree(Word** tree, const char* input) {
int res;
//See if we have found the spot to insert the node.
//Do this by checking for NULL
if (!(*tree)) {
if (!(*tree = createNode(input)))
return BUILD_FAILED;
//Maybe other checks
return BUILD_OK;
}
//else, move left or right accordingly.
if (strcmp(input, (*tree)->data) < 0)
res = buildTree(&(*tree)->left, input);
else
res = buildTree(&(*tree)->right, input);
return res;
}

Clear the last element from a linked list

I am working on a C program which has a linked list. I need to remove the last element from the linked list and it is mostly working except when it hits particular part of my code it then has a segmentation fault.
The code that I have is as follows:
int clearOutboundLegFromList(callLogSearchOutboundStruct ** outboundLeg, int dataCol, int rowTargets)
{
//callLogSearchOutboundStruct *currentStruct = *outboundLeg;
//callLogSearchOutboundStruct *temp;
if (*outboundLeg == NULL)
{
return 0;
}
SL_DebugAll(DBG_ALWAYS, "DEBUG: Clearing outbound legs: DataCol: %i RowTargets: %i",
dataCol, rowTargets);
callLogSearchOutboundStruct *legToRemove = NULL;
callLogSearchOutboundStruct *last = NULL;
legToRemove = *outboundLeg;
while (legToRemove->nextLeg != NULL)
{
last = legToRemove;
legToRemove = legToRemove->nextLeg;
}
if (legToRemove->target != NULL)
{
free(legToRemove->target);
legToRemove->target = NULL;
}
if (legToRemove->cleardownCause)
{
free(legToRemove->cleardownCause);
legToRemove->cleardownCause = NULL;
}
free(legToRemove);
if (last != NULL)
{
last->nextLeg = NULL;
}
legToRemove = NULL;
}
It crashes on the line of free(legToRemove->target);.
In the core dump I have the following:
Program terminated with signal 11, Segmentation fault.
#0 0x00b01336 in _int_free () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.23-13.el6_3.1.i686 glibc-2.12-1.132.el6_5.2.i686 keyutils-libs-1.4-4.el6.i686 krb5-libs-1.10.3-15.el6_5.1.i686 libcom_err-1.41.12-18.el6.i686 libcurl-7.19.7-37.el6_5.3.i686 libidn-1.18-2.el6.i686 libselinux-2.0.94-5.3.el6_4.1.i686 libssh2-1.4.2-1.el6.i686 mysql-libs-5.1.73-3.el6_5.i686 nspr-4.9.2-1.el6.i686 nss-3.14.0.0-12.el6.i686 nss-softokn-freebl-3.12.9-11.el6.i686 nss-util-3.14.0.0-2.el6.i686 openldap-2.4.23-31.el6.i686 openssl-1.0.1e-16.el6_5.14.i686 zlib-1.2.3-29.el6.i686
(gdb) bt
#0 0x00b01336 in _int_free () from /lib/libc.so.6
#1 0x0805cd0b in clearOutboundLegFromList (outboundLeg=0xb5de7984, dataCol=9, rowTargets=11) at performreport.c:6731
#2 0x08058f33 in processDrilldownData (reportParameterArray=..., csvFile=0x8e3fc78, HandleDB=0xbfca7a14, resultReport=0x8e457a8,
If I print from the core dump legToRemove->target gdb outputs the following:
$1 = 0x99235d8 ""
Now that looks like its a properly allocated memory space, it just contains an empty string so I don't understand why this would cause a segfault.
You don't show how your struct looks like or how you add legs to your linked list, but you have an error in your removal function that occurs if you remove the last node: In that case, your list head should be set to NULL.
This special case is the reason to pass the list head as pointer to pointer to leg: The function must be able to update the head when the first node is removed. If you don't do that, the value of the head in the calling function will be the same and it will refer to memory that you have just freed. It is illegal to access such memory.
So, an updated version of your code could look like this:
void clearOutboundLegFromList(callLogSearchOutboundStruct **outboundLeg)
{
callLogSearchOutboundStruct *last = NULL;
legToRemove = *outboundLeg;
if (legToRemove == NULL) return;
while (legToRemove->nextLeg) {
last = legToRemove;
legToRemove = legToRemove->nextLeg;
}
free(legToRemove->target);
free(legToRemove->cleardownCause);
free(legToRemove);
if (last) {
last->nextLeg = NULL;
} else {
*outboundLeg = NULL;
}
}
You need the explicit assignment at the end, because once you have initialised legToRemove, you are operating only with that local pointer.
If you are feeling more confident with double indirections via pointers to pointers, you could iterate to the end without local variabes:
void clearOutboundLegFromList(callLogSearchOutboundStruct **outboundLeg)
{
if (*outboundLeg == NULL) return;
while (*outboundLeg) {
outboundLeg = &(*outboundLeg)->nextLeg;
}
free((*outboundLeg)->target);
free((*outboundLeg)->cleardownCause);
free(*outboundLeg);
*outboundLeg = NULL;
}
This will update the head pointer automatically when the first element is removed. The idea here ist that outboundLeg points to the head node at the beginning and to the previous node's nextLeg pointer on subsequent iterations. The additional indirection via (*outboundLeg) is more or less the same as accessing a node via the nextLeg member, except for the first node, in which you access the pointer through the head node pointer.
(Distraction: Your code is overly cautious when freeing the member pointers. It is legal to free a null pointer; this doesn't do anything, but means that you don't have to check for NULL in client code. Such a check might still be good practice, because many functions won't take null pointers. Setting the member pointers to NULL is a good idea if these pointers were still around for some time. But you are going to free the containing struct anyway soon. Setting the pointers to NULL is a bit like cleaning the bathroom just before you tear down the house. Setting legToRemove to NULL at the end of the function doesn't do anything: The pointer will go out of scope anyway. That's just an aside and retionale for my shorter code. Your checks aren't wrong and it is better to be cautious.)

How to use free on a handle inside a list?-> C -> windows API

I have a list in C that is something like this:
typedef struct _node
{
int number;
DWORD threadID;
HANDLE threadH;
struct *_node next;
} *node;
And you have somthing like this:
node new_node = malloc(sizeof(node));
As you may have guessed out, this list will store information for threads, including their handlers and Id's. Still I am having trouble when I try to do this:
free(new_node);
Everytime I try to do this I encounter an unexpected error, VS saying that there was a data corruption. I've pinned down as much as possible and I found that the problem resides when I try to use free the handle.
I've searched on MSDN how to do this but the only thing I can find is the function that closes the thread (which is not intended here, since I want the thread to run, just deleting it's record from the list).
The question is: how I am supposed to free an handle from the memory? (Considering that this is only a copy of the value of the handle, the active handle is not being deleted).
EDIT: This is the function to insert nodes from the list:
int insereVisitanteLista(node* lista, DWORD threadID, HANDLE threadH, int num_visitante)
{
node visitanteAnterior;
node novoVisitante = (node)malloc(sizeof(node));
if(novoVisitante == NULL)
return 0;
novoVisitante->threadID = threadID;
novoVisitante->threadH = threadH;
novoVisitante->number = num_visitante;
novoVisitante->next = NULL;
if(*lista == NULL)
{
*lista = novoVisitante;
return 1;
}
visitanteAnterior = *lista;
while(visitanteAnterior->next != NULL)
visitanteAnterior = visitanteAnterior->next;
visitanteAnterior->next =novoVisitante;
return 1;
}
And this is the function to delete nodes:
int removeVisitanteLista(node * lista, DWORD threadID)
{
node visitanteAnterior = NULL, visitanteActual;
if(*lista == NULL)
return 0;
visitanteActual = *lista;
if((*lista)->threadID == threadID)
{
*lista = visitanteActual->next;
visitanteActual->next = NULL;
free(visitanteActual);
return 1;
}
while(visitanteActual != NULL && visitanteActual->threadID != threadID)
{
visitanteAnterior = visitanteActual;
visitanteActual = visitanteActual->next;
}
if (visitanteActual == NULL)
return 0;
visitanteAnterior->next = visitanteActual->next;
free(visitanteActual);
return 1;
}
What exactly is a node that you are trying to free? Is this a pointer to a struct _node? If yes, have you allocated it previously? If no, free is not needed, otherwise you have to check if node is not NULL and make sure you do not free it multiple times. It is hard to guess what you are doing and where is an error without a minimal working example reproducing the problem. The only thing I can suggest is to read about memory management in C. This resource might help.
UPDATE:
node in your code is a pointer to _node. So sizeof (node) is a size of a pointer, which is either 4 or 8 bytes (depending on architecture). So you allocate 8 bytes, for example, but assume you have a pointer to the structure which is much larger. As a result, you corrupt memory, and behavior of the program becomes undefined. So changing node novoVisitante = (node)malloc(sizeof(node)) to node novoVisitante = (node)malloc(sizeof(_node)) should fix the problem.
You haven't shown us the context of your call to free() so I need to speculate a little but my first concern is that you didn't mention removing the node from the list before deleting it.
Start by unlinking the node by modifying the next field of the previous (or head) node. If you still get the error, then you have corrupted memory somehow by writing past the end of one of your allocated memory structures or something similar.
Also, I assume node is a pointer. You really haven't provided much information about what you're doing.

Resources