I'm getting a SIGTRAP signal when trying to free an dynamically created array, and have no idea on why.
I'm allocating the array like this:
int* visited = (int*) malloc( l.nodeCount * sizeof(int));
(l.nodeCount is an integer. In the instance of the program I get this error, it is set to 12.)
And when I try to free(visited), I get the SIGTRAP signal in the debugger.
The whole function is this one:
int Graph_GetSmallestPathCount(AdjacencyList l, int destination){
//One path if destination is root
if(destination == 0) return 1;
if(l.nodeCount == 0)
return 0;
Queue reading = Queue_NewQueue();
Queue storing = Queue_NewQueue();
/*Allocates visited array*/
int* visited = (int*) calloc( l.nodeCount, sizeof(int));
/*Visited array initialization*/
int i;
for(i = 0; i < l.nodeCount; i++)
visited[i] = 0;
/*Marks root node and enqueues it*/
visited[0] = 1;
Queue_Enqueue(&reading, 0);
//While there are nodes to read
while(!Queue_IsEmpty(reading))
{
//Dequeues a node
int v = Queue_Dequeue(&reading);
//Gets it's adjacency list
List* currentList = AdjacencyList_GetAdjacentNodes(l, v);
listCell* auxCell = currentList->head->next;
//While there are nodes in it's adjacency list
while(auxCell != NULL){
//Enqueues it if it has not been visited
if(visited[auxCell->data] == 0){
Queue_Enqueue(&storing, auxCell->data);
}
//Adds to the paths to that node
visited[auxCell->data] += visited[v];
auxCell = auxCell->next;
}
//When the queue ends
if(Queue_IsEmpty(reading)){
//If the destination has been reached, return
if(visited[destination] > 0){
Queue_Destroy(&reading);
Queue_Destroy(&storing);
return visited[destination];
}
else{
//Switch queues
Queue_Destroy(&reading);
reading = storing;
storing = Queue_NewQueue();
}
}
}
//Destination has not been reached before end of algorithms. Deallocate everything and return 0
free(visited);
Queue_Destroy(&reading);
Queue_Destroy(&storing);
return 0;
}
Sorry for the lack of comments, I did this on a run and didn't put any in. Also sorry for the printf overload, I put them there while trying to pinpoint the problem.
EDIT: I cleaned it up a little.
The weird thing is that the program works for certain inputs and doesn't for others.
Hope someone can help me out =D
I can't tell you why you get a SIGTRAP as you haven't published a minimal example.
However, I can tell you how to find out out yourself:
Make your program readable. Use one instruction per line. The indent tool is your friend. Sure, that won't fix the bug, but it will make it easier for you to find it.
Don't malloc like that. There is no need to cast the return value of malloc, and using calloc(l.nodeCount, sizeof (int)); or similar is more readable anyway.
What SIGTRAP actually means is you've hit a breakpoint instruction. No doubt what's actually happening is that you've jumped to something which is not your code, and might not be code at all, but contains the binary code for a breakpoint. Why did that happen? The normal cause would be memory corruption, particularly stack corruption. I'm guessing free() is corrupting its own stack. And I'd guess the reason for that is because you are (somewhere) writing to memory outside the memory you've allocated. To test this, run your program with the malloc()/calloc() immediately followed by the free() and an exit(0). If that works, you know the issue is something you are doing between.
We can't tell what you are doing between because you haven't (thankfully) posted the full program, but try running it under valgrind. When you get an out-of-range write, valgrind will normally pick it up. Fix every valgrind warning. That doesn't guarantee a solution, but will find one 95% of the time in my experience.
Also note that return visited[destination]; appears to exit the function without free()-ing visited, which is thus a memory leak.
First, don't call malloc() like that. l.nodeCount * sizeof(int) could potentially exceed INT_MAX, and you'll either have a security hole or if you're lucky, a crash.
Instead, use calloc(l.nodeCount, sizeof(int)).
You should also check the return value of malloc or calloc for NULL in the event your program runs out of memory to allocate.
Found the answer. There was indeed a chance that on specific cases the array would be created with one element less than it should. My bad.
Thanks to all who helped =D
Related
I have created a linked list with the following code. As you can see, I have used malloc to created a list of size 3. But I ran the for loop over size 10 to initialize and print.
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct node {
int value;
struct node *next;
};
int main() {
//code
struct node **head;
struct node *curr;
curr = (struct node *) malloc(sizeof(struct node)*3);
head = &curr;
printf("done 1\n");
(*head)->value = 0;
(*head)->next = NULL;
for(int i = 1; i < 10; i++) {
(*head+i-1)->next = (*head+i);
(*head+i)->value = i;
(*head+i)->next = NULL;
}
curr = *head;
printf("done 2\n");
for(int i = 0; i < 10; i++) {
printf("%d\t", (*head + i)->value);
//curr = curr->next;
}
printf("\ndone 3\n");
//free(curr);
return 0;
}
when I compile and run the code, the result obtained is,
done 1
done 2
0 1 2 3 154208560 842282289 876087600 154744882 808859448 875837236
done 3
Why am I able to assign values to the 4th node and access it when I actually created a list of size 3?
I see that garbage values were being printed from 5th to 10th node access. But how is the 4th node being created?
P.S:
I know that 10!=3. The code ran properly when I put the loop in its limits. I wanted to see what will happen when we go out of bounds. I see that the 4th node was also created as I was able to assign value when I actually created a list of size 3.
This is purely to see if I will get seg fault or not.
You're invoking undefined behavior. When you do this, the program may crash, it may appear to work properly, or it might behave in a seemingly random manner.
C doesn't perform any kind of bounds checks on arrays or allocated memory. It's one of the things that makes it fast. What that also means is that it will allow you to do things you're not supposed to do. It trusts the programmer to "do the right thing".
On your particular machine, you see random data after the third element. When I run the same code on my machine, I happen to get the expected output as though enough memory was allocated. Also, if I uncomment the call to free, the program crashes. That's undefined behavior.
Trying to understand undefined behavior is usually a futile effort. It all depends on the implementation details of your compiler and the machine it runs on. In this case, the memory being written to was probably unallocated memory in the heap after the memory that was properly allocated. Depending on how malloc is implemented, that part of memory may contain data needed for malloc and other functions to run properly. The point is that writing past the end of an array does not guarantee a crash, so you need to be careful.
This code will behave differently on the different operating systems.
You may get away even with assigning all 10 integers and print then correctly.
Your code puts the beginning of list on the heap with allocations for only 3 elements.
You may get lucky and use memory for all 10 element or your program will crash on the 4-th!
I have a problem with this code, I tried to understand what's going on, but I cannot understand why it just crushes. the functions works like I expect for the node->left.
But when the last call of the function ends in the case node->left; the function just crushes, I think because of the reallocated array, I don't know if I'm trying to access a forbidden memory.
I'll explain a little more where I think the problem comes from:we are in the last call of helper(node->left,table,len) before printing the array : consider len = N and node->left!=NULL ==> reallocating table len = N+1, assigning node->data to table[len] and everything is fine, node->left == NULL ==> printing the table and we are done with the helper(node->left,table,N) case; now we are in the helper(node->right,table,N) case; in this case the program just crushes ; it's supposed to reallocate table; and assign node->data to table[N]; and so one ...
By the way : this function tries to print all the Root-leaf paths in a binary tree.
struct node {
int data;
struct node* left;
struct node* right;
};
void helper(struct node* node,int *table,int len)
{
if(node == NULL){
return;
}
else{
table = realloc(table,(len+1)*sizeof(int));
table[len]=node->data;
len = len +1;
if(node->left == NULL && node->right == NULL)
{
int cmt=0;
for(cmt = 0; cmt < len ; cmt++ ){
printf("%d ->",table[cmt]);
}
}
else{
helper(node->left,table,len);
helper(node->right,table,len);
}
}
}
void print_rtl(struct node* node) {
if(NULL == node) return;
else{
int *t=malloc(sizeof(int));
t[0]=node->data;
int lenght = 1;
helper(node->left,t,1);
helper(node->right,t,1);
}
}
Here is the thing about realloc: it has the freedom to change not just the size of the allocated memory block, but also its location. In general, realloc can break any pointers you have that are pointing to objects in the block of memory that was realloced. When you try to use those pointers later, you will get undefined behavior.
You should either allocate enough memory at the beginning of your program that you won't need to call realloc, or you should redesign your program so you don't need to allocate that memory block in the first place, or you should make your table pointer be a global variable so that when you change its value, it gets updated for every function that is using the table.
Right now the problem with your code is that when you call helper, it might call realloc and change the location of your table, but it doesn't communicate that change to the caller in any way, so the caller doesn't know where the table is located.
There might be other problems with your code. If you continue to have trouble, I strongly urge you to produce an MCVE and post that in your next question. Doing that makes it much easier for someone else to reproduce your problem and find a solution to it that actually works.
It's hard to tell exactly what going on because it quite a big mess, but generally... The first thing helper() does (after validating node!=NULL) is reallocate table. That means when you get to the recursion point, helper(node->left.. will reallocate, and then immediately after helper(node->right.. will also try to do so, but on an invalid pointer. From there on, it's a wild ride to exceptions...
I have a function that takes a string and cuts out a some parts of it.
The function does its thing a couple of times until, all of a sudden, the same malloc line that worked fine, crashes with No source available for "0xb7e88a81" error.
Tried to clear out every thing to make sure I'm not sending NULL length or whatever, but still no luck.
It worked at least once (debugged it) but on the second or third iteration it crashes.
char *removeOffsetFromLabel (char *label) {
char* labelWithoutOffset;
int i;
labelWithoutOffset = malloc(strlen(label));
........
The crash happens on the malloc line (when trying to move to the next line).
strlen(label) = 7 (checked it)
Any ideas ? I'm using GCC compiler on Eclipse (Ubuntu).
Per FoggyDay's request this is the whole function:
char *removeOffsetFromLabel (char *label) {
char* labelWithoutOffset;
int i;
labelWithoutOffset = (char*)malloc(strlen(label) + 1);
i = 0;
while (label[i] != '\0' && label[i] != OPENING_BRACKET_ASCII_CODE) {
labelWithoutOffset[i] = label[i];
i++;
}
labelWithoutOffset[i] = '\0';
return labelWithoutOffset;
}
I do free up "labelWithoutOffset" outside of the function before calling it again.
I wish I could mark all of your answers with V sign to indicate it solved the issue since you've been most helpful.
After digging in I made two changes to my code and things seem to be working fine so far:
Removed two "free" commands that were used on an already freed up pointers (dumb mistake)
Added "pointer = NULL" after every free (just to be on the safe side)
Again, I thank all of you for showing me other issues I had in my code.
StackOverflow ROCKS !
1) As already mentioned above, "malloc()" MUST BE "strlen()+1":
char *removeOffsetFromLabel (char *label) {
char* labelWithoutOffset = (char *)malloc(strlen(label)+1);
2) Since this didn't solve the problem, we also need to look at:
a) is "label" valid when we call strlen()?
b) do you have any code that might be overwriting "labelWithoutOffset" somewhere else - after you've allocated it in one call, and before you allocate it again in a different call?
SUGGESTIONS:
a) Add this code (or better, look at "label" in your debugger):
char *removeOffsetFromLabel (char *label) {
fprintf (STDERR, "label=%s\n", label);
fprintf (STDERR, "strlen(label)=%d\n", strlen(label);
char* labelWithoutOffset = (char *)malloc(strlen(label)+1);
b) Post some more code from "removeOffsetFromLabel()" - maybe we can see where the variable might be "getting stepped on".
PS:
If you're feeling ambitious, check out my link to the Valgrind tutorial above it.
But for "quick results", please try suggestions 1) and 2); and let us know how it goes.
if strlen(label) is indeed 7, than it's not strlen() but malloc() itself that crashes.
If malloc() crashes, that probably means malloc()'s internal housekeeping was destroyed earlier/elsewhere (by a pointer gone crazy).
Bugs like this are hard (hardest) to find since you can't tell where they are because the crash is likely happening long after the cause.
You might want to look into Valgrind usage.
Scratch that.
i dont understand whatever function type that is there, but to my knowledge of malloc(); and strings, since label is an array you should send it like this
void funcCall(int *)
main()
{
funcCall(label)
}
funcCall(int funcLabel[])
{
}
hope this helps.
I wonder if anyone might have any insight on this...
My program is crashing on this call:
void subtract(data* array,data* inverse,int a, int b, int q, int n)
{
data* arraytomultiply;
arraytomultiply = (data *)malloc(sizeof(data*) * n);
Where data just holds an int (it's for convenience when switching types later)
typedef struct {
int value;
}data;
I've tried lots of messing around with changing the pointers here as I'm not confident on them at all, but to no avail.
The strange thing is, much earlier in the program this same call works, I assign values to it and can print them out and everything..:
data* array;
array = (data*)malloc(sizeof(data*) * m * n); // m * n entries
One thing that might be of use (though I have no idea why) is that when it works earlier it's during a void function, whereas when it crashes it's in a function called from within an algorithm. but I don't see how this could affect it at all, given what I'm trying to do isn't using any of the arguments etc...
Any ideas?
Shouldn't that be sizeof(data) instead of sizeof(data*) since you're allocating space for data structures?
You are allocating m * n elements of data * and not data. If you want array of pointers to data then what you are doing in malloc() is correct but that should be assigned to data **
array = (data*)malloc(sizeof(data*) * m * n); // m * n entries
It should be
array = (data*)malloc(sizeof(data) * m * n); // m * n entries
and, you should always check the return value of malloc() to find whether it fails or succeeds!
if ((array = (data*)malloc(sizeof(data) * m * n)) == NULL) {
printf("unable to allocate memory");
return; // you can return your error code here!
}
Your program has all the reason to crash. But when you said, it worked earlier but crashed later made be to do some experiments. I tried your code snippet and found it working for me. I tried many a times but it never crashed. I got puzzled and I posted a question to find out why?! - It is available here Are "malloc(sizeof(struct a *))" and "malloc(sizeof(struct a))" the same?
+1 to your question!
You all are right, but anyhow I wonder why this crashes.
I wonder because the size of data (as defined above) is expected to be less or equal to the size of data*.
When malloc crashes, it is usually because you have messed up the structures it uses to track memory on the heap somewhere else. Is your program multi-threaded? Try running it with helgrind or drd (both valgrind tools). These can help you track down race conditions, unprotected data accesses, or other threading issues.
I have a monte carlo simulation, that is supposed to run multiple times and then average over the individual results. After each run, I want to free the allocated memory for the stuff I need in the simulation. One piece of this stuff is an array of sites, where each site is a struct that has a linked list of type SLE as one member. So in order to free all of it, I first iterate through the linked list and free each node and then free the memory of the sites array.
SLE * neighbor, * tmp;
int i;
for(i = 0; i < args.nsites_arg; ++i)
{
// free neighbor memory
neighbor = sites[i].neighbors;
while(neighbor)
{
tmp = neighbor->next;
free(neighbor);
neighbor = tmp;
}
}
free((void *)sites);
There is, however, something very weird happening: The simulation runs fine once and then starts over again. I reallocate all the needed memory for sites and rewrite the mentioned linked list of SLEs. Then, in some sorting operation on the former array, it gives mit a segfault:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000408468 in sortNeighbors (list=0xad0e00) at mc_init.c:485
485 while(temp && temp->next)
When I remove the free(neighbor) in the above snippet, it works fine. As I said, everything is reallocated just like before the first run. So what happens here? How could I gather more information on what is really freed and why this segfault is happening?
Edit: The other weird thing is, that the beginning of this sorting looks like this:
if (!list || !list->next)
return list;
SLE * temp = list;
// Find halfway through the list
while(temp && temp->next)
{
I explicitely check if list and list->next exist, so why is it giving a segfault in the while condition?
Edit2: The allocation
sites = (Site *) malloc(args.nsites_arg * sizeof (Site));
...
// s is now one element of the sites array
while(siteList)
{
neighbors = (SLE*) malloc(sizeof (SLE));
...
neighbors->next = s->neighbors;
s->neighbors = neighbors;
siteList = siteList->next;
}
If you are on linux, take a look at my answer here. It's about valgrind, a tool that helps debugging segfaults, memory leaks etc.
When you get SIGSEV by accessing freed memory (your case as I understand), it tells you where the memory was freed - it is not necessary that it was freed by the free call in your snippet.
Before searching for a bug, you might want to use an already implemented well tested single or double linked lists.
Or, if you don't want to bother with the mem bug, link against gc garbage collector (assuming the actual calculation of your simulation does what it should do)
Some more good commercial tools for Windows:
Purify
Insure++
Try running it through valgrind: valgind --tool=memcheck [COMMAND]
It works out of the box, nothing special needed.
For more info goto the Valgrind website.