Segmentation fault at the end of the program in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
A segmentation fault occurs after everything has been executed. I tried for hours but still can't find the problem. I feel depressed and any assistance is appreciated!
All the code are under directory "KNN - GitHub" in this link: https://ide.c9.io/captainzidane/kd_tree
point.txt, test2.c, kdtree.c, kdtree.h are to be used.
Here is part of my "test.c" file, where the seg fault occurs at the last line. i.e., the last closing brace }
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "kdtree.h"
#define DEF_NUM_PTS 10
#define MAX_NUM_OF_POINTS 20000
#define DIMENSION 3
int main (int argc, char *argv[]) {
//int arraySize;
double pointArray[MAX_NUM_OF_POINTS][DIMENSION];
FILE *coordFile = fopen ("points.txt", "r");
//coord *coords = malloc(sizeof(coord) * MAX_NUM_OF_POINTS);
int lineCounter = 0;
while (fscanf (coordFile, "%lf %lf %lf", &pointArray[lineCounter][0], &pointArray[lineCounter][1],
&pointArray[lineCounter][2]) == 3 && lineCounter < MAX_NUM_OF_POINTS) {
lineCounter++;
}
double range = 8.1;
int num_of_nearest;
double queryPoint[DIMENSION];
int counter;
int dist;
int num;
//scanf ("%lf %lf %lf %d", &queryPoint[0], &queryPoint[1], &queryPoint[2], &num);
queryPoint[0] = 1;
queryPoint[1] = 5;
queryPoint[2] = 8;
num = 10;
//Build and insert points to a KD Tree
struct kdtree *newTree = buildTree (pointArray);//////make it run only once
//Return nearst N nodes and distance in order from smallest to largest
struct knn_result *res_n = knn(newTree, queryPoint, num);
free (res_n);
printf ("======================================================\n");
//Return nodes within a range of the query point
struct nn_range *res_range = nn_range(newTree, queryPoint, range);
free (res_range);
printf ("======================================================\n");
fclose (coordFile);
kd_free(newTree);///To be deleted
return EXIT_SUCCESS;
}
Here is the part of my "kdtree.c" file which contains the function which may cause the error:
struct nn_range {
double nearestRange[MAX_NUM_OF_POINTS][DIMENSION+1];
int nPoints;
};
struct nn_range *nn_range (struct kdtree *tree, const double *queryPoint, double range)
{
printf ("Nodes within a radius of %.3f to the query point:\n", range);
printf ("-------------------------------------------------\n");
struct kdres *presults_range = kd_nearest_range(tree, queryPoint, range);
double temp[3] = {0};
double dist_temp = 0;
struct nn_range *res = malloc(sizeof(struct nn_range));
int counter = 0,i;
res->nPoints = kd_res_size(presults_range);
printf("found %d results within the radius of %.3f\n", res->nPoints, range);
while(!kd_res_end( presults_range) && counter < res->nPoints)
{
dist_temp = 0;
/* get the data and position of the current result item */
kd_res_item(presults_range, temp);
/* compute the distance of the current result from the pt */
for(i=0; i<DIMENSION; i++)
{
dist_temp += SQ(queryPoint[i] - temp[i]);
}
dist_temp = sqrt(dist_temp);
res->nearestRange[counter][0] = temp[0];
res->nearestRange[counter][1] = temp[1];
res->nearestRange[counter][2] = temp[2];
res->nearestRange[counter][3] = dist_temp;
/* print out the retrieved data */
printf("node at (%.3f, %.3f, %.3f) is %.3f away\n", res->nearestRange[counter][0],
res->nearestRange[counter][1],
res->nearestRange[counter][2],
res->nearestRange[counter][3]);
/* go to the next entry */
kd_res_next(presults_range);
counter++;
}
kd_res_free(presults_range);
return res;
}
GDB said
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ab9 in main (argc=1, argv=0x7fffffffe1d8) at test2.c:117
117 }
Valgrind said
==5369== Jump to the invalid address stated on the next line
==5369== at 0x3FE970FD6F3D35D2: ???
==5369== by 0x3FED48EE17391B6D: ???
==5369== by 0xFFF000157: ???
==5369== by 0xFFFFFFFF: ???
==5369== by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369== Address 0x3fe970fd6f3d35d2 is not stack'd, malloc'd or (recently) free'd
==5369==
==5369==
==5369== Process terminating with default action of signal 11 (SIGSEGV)
==5369== Bad permissions for mapped region at address 0x3FE970FD6F3D35D2
==5369== at 0x3FE970FD6F3D35D2: ???
==5369== by 0x3FED48EE17391B6D: ???
==5369== by 0xFFF000157: ???
==5369== by 0xFFFFFFFF: ???
==5369== by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369==
==5369== HEAP SUMMARY:
==5369== in use at exit: 0 bytes in 0 blocks
==5369== total heap usage: 40,057 allocs, 40,057 frees, 2,561,888 bytes allocated
==5369==
==5369== All heap blocks were freed -- no leaks are possible
==5369==
==5369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==5369==
==5369== 1 errors in context 1 of 1:
==5369== Jump to the invalid address stated on the next line
==5369== at 0x3FE970FD6F3D35D2: ???
==5369== by 0x3FED48EE17391B6D: ???
==5369== by 0xFFF000157: ???
==5369== by 0xFFFFFFFF: ???
==5369== by 0x4008BC: ??? (in /home/ubuntu/workspace/KNN - GitHub/c)
==5369== Address 0x3fe970fd6f3d35d2 is not stack'd, malloc'd or (recently) free'd
==5369==
==5369== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
Here is part of the output
Nodes within a radius of 8.100 to the query point:
-------------------------------------------------
found 24 results within the radius of 8.100
node at (0.718, 0.958, 0.994) is 8.093 away
node at (0.716, 0.974, 0.992) is 8.087 away
node at (0.629, 0.960, 0.991) is 8.099 away
node at (0.629, 0.960, 0.991) is 8.099 away
node at (0.556, 0.994, 0.979) is 8.096 away
node at (0.677, 0.985, 0.991) is 8.084 away
node at (0.556, 0.994, 0.979) is 8.096 away
node at (0.677, 0.985, 0.991) is 8.084 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.909, 0.966, 0.980) is 8.097 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.978, 0.958, 0.993) is 8.089 away
node at (0.857, 0.970, 0.978) is 8.098 away
node at (0.862, 0.985, 0.984) is 8.085 away
node at (0.862, 0.985, 0.984) is 8.085 away
node at (2.000, 2.000, 2.000) is 6.782 away
node at (2.000, 2.000, 2.000) is 6.782 away
node at (1.000, 1.000, 1.000) is 8.062 away
node at (1.000, 1.000, 1.000) is 8.062 away
node at (1.000, 2.000, 2.000) is 6.708 away
======================================================
Segmentation fault

A segmentation fault occurs after everything has been executed
In 99.9% of the cases this happens because you overflow a stack buffer allocated in main, and step on (corrupt) mains return address, so it returns to a "garbage" address.
I tried for hours but still can't find the problem
There are a few ways to find such problems:
Code inspection. Now that you know what to look for, examine all stack buffers in main, and check that you don't write to any of them out of bounds.
Allocate an extra buffer of 256 bytes before your first stack buffer in main, and after the last such buffer. Fill these extra buffers with a known sentinel value, and verify that the sentinel values are still intact just before returning from main. They likely wouldn't be. Once you know which sentinel value is getting corrupted, use GDB watchpoint to find which code writes to that address.
Valgrind (which you have tried) is very weak at detecting stack overflows. You could convert some of your stack buffers to be heap-allocated, and Valgrind will tell you right away where the overflow happened.
If you have a relatively recent compiler, both Clang and GCC support Address Sanitizer (-fsanitize=address), which is excellent at detecting both heap and stack overflows, and will likely point you straight at the problem.
All the code are under directory "KNN - GitHub"
That site requires a login. You don't seriously believe we all are going to sign up for an account there just so we can tell you exactly what the problem is? Next time, try to put your code somewhere more easily accessible.

Related

Why am I getting "invalid read" and "invalid write" from valgrind with the following code?

I am writing a program to make sure I understand how to correctly implement a singly linked list in C. I'm currently in the middle of Harvard's CS50 course, and using this tutorial since the CS50 people don't explain the linked list data structure in a lot of detail: https://www.youtube.com/watch?v=7Fz7JSvlr9g
The code seems to function ok, but I am getting "invalid read" and "invalid write" errors when I check it using valgrind.
Here's my code:
// creating and using a singly linked list in C
#include <stdio.h>
#include <stdlib.h>
// create structure for nodes
typedef struct sllist
{
int val;
struct sllist *next;
}
sllnode;
// function declarations
sllnode *create(int sz);
void display(sllnode *head);
int main(void)
{
// declare head node and set to NULL
sllnode *head = NULL;
// prompt for size of list
printf("how many numbers would you like to store? ");
int sz;
scanf("%i", &sz);
// create linked list (create passes head pointer back to head)
head = create(sz);
// display linked list
display(head);
}
// function for creating a linked list
sllnode *create(int sz)
{
// initialize head pointer to NULL
sllnode *head = NULL;
// initialize temp pointer (for creating new nodes in the upcoming for loop)
sllnode *temp = NULL;
// initialize p for iterating through the list
sllnode *p = NULL;
for (int i = 0; i < sz; i++)
{
// allocate space for individual node
temp = (sllnode *)malloc(sizeof(sllnode));
// check to make sure we haven't run out of memory
if (temp == NULL)
{
printf("Couldn't allocate memory\n");
exit(1);
}
// prompt user for value to store
printf("enter the value #%i: ", i + 1);
scanf("%i", &(temp->val));
// intialize temp's next pointer to NULL
temp->next = NULL;
// if running first time (linked list is empty) temp becomes the head node
if (head == NULL)
{
head = temp;
}
// if the loop has run a few times (list not empty)
else
{
// start at the head
p = head;
// iterate through the list to find the last node
while (p->next != NULL)
{
p = p->next;
}
// set that node's pointer to the new node
p->next = temp;
}
free(temp);
}
// give the head pointer back to main
return head;
}
// function for displaying the linked list
void display(sllnode *head)
{
// initialize pointer p to head (coming from main)
sllnode *p = head;
// iterate through the list, printing a new value each time
while(p != NULL)
{
printf("%i -> ", p->val);
p = p->next;
}
printf("\n");
}
And here's the output from valgrind:
==4407== Memcheck, a memory error detector
==4407== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4407== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4407== Command: ./ll0
==4407==
how many numbers would you like to store? 2
enter the value #1: 1
enter the value #2: 6
==4407== Invalid read of size 8
==4407== at 0x4209DA: create (ll0.c:74)
==4407== by 0x420713: main (ll0.c:29)
==4407== Address 0x6183048 is 8 bytes inside a block of size 16 free'd
==4407== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4407== by 0x420B73: create (ll0.c:81)
==4407== by 0x420713: main (ll0.c:29)
==4407==
==4407== Invalid write of size 8
==4407== at 0x420B65: create (ll0.c:79)
==4407== by 0x420713: main (ll0.c:29)
==4407== Address 0x6183048 is 8 bytes inside a block of size 16 free'd
==4407== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4407== by 0x420B73: create (ll0.c:81)
==4407== by 0x420713: main (ll0.c:29)
==4407==
==4407== Invalid read of size 4
==4407== at 0x420CAA: display (ll0.c:96)
==4407== by 0x420720: main (ll0.c:31)
==4407== Address 0x6183040 is 0 bytes inside a block of size 16 free'd
==4407== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4407== by 0x420B73: create (ll0.c:81)
==4407== by 0x420713: main (ll0.c:29)
==4407==
1 -> ==4407== Invalid read of size 8
==4407== at 0x420D62: display (ll0.c:97)
==4407== by 0x420720: main (ll0.c:31)
==4407== Address 0x6183048 is 8 bytes inside a block of size 16 free'd
==4407== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4407== by 0x420B73: create (ll0.c:81)
==4407== by 0x420713: main (ll0.c:29)
==4407==
6 ->
==4407==
==4407== HEAP SUMMARY:
==4407== in use at exit: 0 bytes in 0 blocks
==4407== total heap usage: 2 allocs, 2 frees, 32 bytes allocated
==4407==
==4407== All heap blocks were freed -- no leaks are possible
==4407==
==4407== For counts of detected and suppressed errors, rerun with: -v
==4407== ERROR SUMMARY: 6 errors from 4 contexts (suppressed: 0 from 0)
Seems like it has something to do with the way I'm accessing the temp node, but I don't really understand the issue.
Because in the create function you free the nodes you just have added to the list.
Simply remove the free(temp); from the function.
The variable name temp is misleading here. It is not at all a temporary node. A correct name for this variable would be newnode.
You should read again the chapter dealing with dynamic memory allocation in your C text book.
Note 1: BTW: In the video you mention there is no free in the create function.
Note 2: Be aware that this algorithm for creating the list is terribly inefficient. In order to find the last element, the whole list is traverses from the head to the last element. In order to be efficient you should maintain the pointer to the last element.

Implementing and using a dynamic array in C

I'm trying to make a list of students that stores structs using a dynamically allocated array. For this I have the following structs:
typedef struct s_student
{
char name[64];
int matrikelNummer;
} student;
typedef struct s_studentList
{
student* students;
int numberOfStudents;
} studentList;
This is how I use them so far:
int main(int argc, char** argv) {
studentList* list = NULL;
list = (studentList*) malloc(sizeof(studentList));
list->numberOfStudents =1;
//list->students->matrikelNummer = 1;
//strcpy(list->students->name , "karim");
printf("numberOfStudents : %d\n" , list->numberOfStudents );
//printf("matrikelNummer : %d\n" , list->students->matrikelNummer);
//printf("name : %d\n" , list->students->name);
free(list);
return 0;
}
That seems to work with no problems. But when I try to assign data to the students (matrikelNummer or name) as outlined in the commented lines, I receive a Segmentation fault.
What am I doing wrong?
Not allocated pointers
The problem is that you do:
// list points to null after that line
studentList* list = NULL;
// allocate memory for the list struct
list = (studentList*) malloc(sizeof(studentList));
// set field inside list struct
list->numberOfStudents =1;
// list->students is a pointer, but pointers should point to something valid
// So the question is: Was list->students set to NULL?
// Or was it mallocated?
list->students->matrikelNummer = 1;
So you access list->students that is a pointer.
List itself was allocated via malloc so its fine.
But malloc reserves space for only the list object you want.
It does not mallocate anything else.
So list->students is a pointer that is not mallocated - that's why we get the segmentation fault error.
Solution to this problem is pretty straightforward - we have to allocate not only a list but all pointers we use (in this case its students member):
// That was earlier there:
studentList* list = NULL;
list = (studentList*) malloc(sizeof(studentList));
// After allocating place for list also allocate place for list->students:
list->students = (student*) malloc(sizeof(student));
Detection of invalid memory usage
In a case when you get segmentation faults or memory leaks it's good to know that there are plenty of tools to help programmers detect such a nasty errors.
One of them is Valgrind
Valgrind is available for Linux (and probably for Windows but buggy and untested).
It's awesome tools that can traverse your program and notify you about any leaks, invalid frees and usage of forbidden memory addresses.
Example usage of Valgrind:
# Compile your code
gcc list.c -o list
# Use Valgrind
valgrind --tool=memcheck ./list
And what valgrind shows:
==26761== Memcheck, a memory error detector
==26761== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26761== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==26761== Command: ./list
==26761==
==26761== Use of uninitialised value of size 8
==26761== at 0x4006A1: main (in /home/students/inf/p/ps386038/stack/list)
==26761==
==26761== Invalid write of size 4
==26761== at 0x4006A1: main (in /home/students/inf/p/ps386038/stack/list)
==26761== Address 0x40 is not stack'd, malloc'd or (recently) free'd
==26761==
==26761==
==26761== Process terminating with default action of signal 11 (SIGSEGV)
==26761== Access not within mapped region at address 0x40
==26761== at 0x4006A1: main (in /home/students/inf/p/ps386038/stack/list)
==26761== If you believe this happened as a result of a stack
==26761== overflow in your program's main thread (unlikely but
==26761== possible), you can try to increase the size of the
==26761== main thread stack using the --main-stacksize= flag.
==26761== The main thread stack size used in this run was 8388608.
==26761==
==26761== HEAP SUMMARY:
==26761== in use at exit: 16 bytes in 1 blocks
==26761== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==26761==
==26761== LEAK SUMMARY:
==26761== definitely lost: 0 bytes in 0 blocks
==26761== indirectly lost: 0 bytes in 0 blocks
==26761== possibly lost: 0 bytes in 0 blocks
==26761== still reachable: 16 bytes in 1 blocks
==26761== suppressed: 0 bytes in 0 blocks
==26761== Rerun with --leak-check=full to see details of leaked memory
==26761==
==26761== For counts of detected and suppressed errors, rerun with: -v
==26761== Use --track-origins=yes to see where uninitialised values come from
==26761== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
So it shows that you access invalid address in function main:
==26761== Invalid write of size 4
==26761== at 0x4006A1: main (in /home/students/inf/p/ps386038/stack/list)
==26761== Address 0x40 is not stack'd, malloc'd or (recently) free'd
And says the address (pointer is not even allocated)!
Correct C list implementation
If you want to implement a pointers structure that holds list of students
then one common approach is to put a pointer to the next student (next on the list) into the s_student structure.
And pointers to the first and last student into the student list.
One working example is the following I wrote myself:
#include <stdio.h>
#include <stdlib.h>
typedef struct s_student student;
struct s_student
{
char name[64];
int matrikelNummer;
// This will point to the next student on the list
student* nextStudent;
};
typedef struct s_studentList
{
student* student;
// This will point to the last available student
student* lastStudent;
// This will point to the first available student
student* firstStudent;
int numberOfStudents;
} studentList;
// Allocates the list
void allocStudentsList(studentList** list) {
if(list == NULL) return;
*list = (studentList*) malloc(sizeof(studentList));
(*list)->lastStudent = NULL;
(*list)->firstStudent = NULL;
}
// To add the student to the list
void addStudentToList(studentList* list, student studentData) {
if(list == NULL) return;
// Allocate a place for the next student
student* st = (student*) malloc(sizeof(student));
// If it's first student in the list
if(list->lastStudent == NULL) {
list->lastStudent = st;
list->firstStudent = st;
} else {
// The next student after the current last student will be the newly created one
list->lastStudent->nextStudent = st;
}
// Fill the student data
*st = studentData;
st->nextStudent = NULL;
// Set the last available student to the one created
list->lastStudent = st;
}
// To recurisvely free the students
void freeStudent(student* stud) {
if(stud->nextStudent != NULL) {
// Free next student recursively
freeStudent(stud->nextStudent);
}
free(stud);
}
// To free the students list
void freeStudentsList(studentList* list) {
if(list != NULL) {
freeStudent(list->firstStudent);
free(list);
}
}
// Function that prints single student and returns next one (after him on the list)
student* printStudent(student* stud) {
if(stud == NULL) return NULL;
printf(" * Student { matrikelNummer = %d }\n", stud->matrikelNummer);
// Return next student
return stud->nextStudent;
}
// Function that prints students list
void printStudentsList(studentList* list) {
if(list == NULL) return;
printf("StudentsList [\n");
student* current_student = list->firstStudent;
while(current_student != NULL) {
current_student = printStudent(current_student);
}
printf("]\n");
}
int main(int argc, char** argv) {
studentList* list = NULL;
allocStudentsList(&list);
// Create some student data
student st1;
st1.matrikelNummer = 1;
// Another student...
student st2;
st2.matrikelNummer = 2;
// Put them into the list (allocates students and take care of everything)
addStudentToList(list, st1);
addStudentToList(list, st2);
// Print the list
printStudentsList(list);
// Free the list (recursively free's all students and take care of all the nasty stuff)
freeStudentsList(list);
return 0;
}
There are plenty of tutorials how to write C-style lists structures on the web.
You can find one yourself.
One of the tutorial is there: Learn-c linked list tutorial
in your s_studentlist struct you have a pointer called students, you never used malloc on this member so its just a pointer to a random chunk in memory, allocate it the same way you did with your list variable
you need to allocate memory for the student. When using malloc you only allocate memory for the list type, which includes a pointer to a student-type but not memory for the student type:
studentList* list = NULL;
list = (studentList*) malloc(sizeof(studentList));
list->students = (student*) malloc(sizeof(student));
Another Problem with you list is that I don't know how it is designed to work.
A list normally contains a pointer to the next element:
typedef struct s_student {
struct s_student* next;
char name[64];
int matrikelNummer;
} student;
Another approach would be to store a list of students as an array in studentList, but hten you would need to allocate memory for more than one student:
list->students = (student*) malloc(list->numberOfStudents * sizeof(student));
This would be no list, but an array and you would access entries with
list->students[0].matrikelNummer

C - Receiving a SIGABRT when freeing structs - System-specific?

I'm currently tinkering with binary trees in C, but I've run into an issue that I can't seem to solve on my own. I'm using Eclipse Mars as my IDE.
The basic idea of the project is to have a binary tree composed out of treeNodes. These nodes are structs and contain a struct within (struct Books), thus there are two separate libs for treeNode and books.
These are the structs in question:
TreeNode:
struct TreeNode {
struct Book *book;
unsigned long key;
struct TreeNode *left;
struct TreeNode *right;
};
Book:
struct Book {
unsigned long ISBN;
char* author_name;
char* book_title;
};
Now, the nodes get created fine and the insertion/print functions work well. However, I also have a clear() function, that is supposed to free any previously allocated memory. Malloc is called only in the new_xxx() functions:
struct TreeNode *new_tree_node(unsigned long ISBN, char *author, char *title) {
//Creating and allocating the new TreeNode
struct TreeNode *new_tree_node;
new_tree_node = (struct TreeNode*) malloc(sizeof(struct TreeNode));
//Creating the book
struct Book *new_Book = newBook(ISBN, author, title);
new_tree_node->book = new_Book;
new_tree_node->left = NULL;
new_tree_node->right = NULL;
new_tree_node->key = ISBN;
return new_tree_node;
}
And newBook():
struct Book *newBook(unsigned long ISBN_nr, char *author_name, char *book_title) {
//Creating and allocating the Book
struct Book *new_Book;
new_Book = (struct Book*) malloc(sizeof(struct Book));
//Assigning Values
new_Book->ISBN = ISBN_nr;
new_Book->author_name = author_name;
new_Book->book_title = book_title;
return new_Book;
}
Now, when I try to run the clear() function, I receive a "SIGABRT:Aborted" signal as soon as I try to free a TreeNode and the process halts. Eclipse also returns:
"No source available for "raise() at 0x75ffff7a4bcc9".
Initially I thought this happened because my system could not find one of the standard functions, but the console also prints:
*** Error in /home/max/workspace/bst_2/Debug/bst_2': double free or corruption (out): 0x00007fffffffe030 ***
which makes me believe that there actually is an issue within the code.
This is the function in question:
void bst_clear(struct TreeNode *tree_node) {
//Clears all nodes recursively
if (tree_node->left != NULL) {
bst_clear(tree_node->left);
}
if (tree_node->right != NULL) {
bst_clear(tree_node->right);
}
tree_node->key = NULL;
tree_node->book = NULL;
free((void*) tree_node);
return;
}
Funny thing is, this does only happen while using a Linux OS (Mint 17.1) - both in a VM and as a dual-boot system. My main OS, which is Windows 7 64-bit, does compile and run without any issues and gets through the process entirely.
I am not sure whether something is actually wrong with the code (which could definitely be the case, I'm still a newbie) or whether my OS did mess something up there. But since this happened both in a VM and an actual system, it probably has nothing to do with missing system libraries (I guess).
So, does anyone have a clue on what's going on here?
EDIT: valgrind output:
==2946== Invalid free() / delete / delete[] / realloc()
==2946== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2946== by 0x4008D3: bst_clear (booktree.c:84)
==2946== by 0x400884: bst_clear (booktree.c:73)
==2946== by 0x400884: bst_clear (booktree.c:73)
==2946== by 0x400D17: main (main.c:66)
==2946== Address 0xfff000030 is on thread 1's stack
==2946==
==2946== Invalid free() / delete / delete[] / realloc()
==2946== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
...
==2946==
==2946==
==2946== HEAP SUMMARY:
==2946== in use at exit: 128 bytes in 4 blocks
==2946== total heap usage: 10 allocs, 10 frees, 280 bytes allocated
==2946==
==2946== LEAK SUMMARY:
==2946== definitely lost: 128 bytes in 4 blocks
==2946== indirectly lost: 0 bytes in 0 blocks
==2946== possibly lost: 0 bytes in 0 blocks
==2946== still reachable: 0 bytes in 0 blocks
==2946== suppressed: 0 bytes in 0 blocks
==2946== Rerun with --leak-check=full to see details of leaked memory
The error appeared multiple times - the line in question is the free() command - line 73 is just the recursive function call.
Now, if I got this right, I'm trying to free an object in the stack - read-only memory, right? The only thing I can think of are the struct declarations, which contain possibly static elements?
I'd also like to point out, that there is ZERO issue when running this on a Windows machine - does anyone know the reason for this?
EDIT 2:
This is how nodes are created:
char* root_author;
char* root_title;
root_author = "A B C\0";
root_title = "ABC\0";
struct TreeNode *root;
root = new_tree_node(579610, root_author, root_title);
char* n1a;
char* n1t;
n1a = "B C D";
n1t = "BCD";
struct TreeNode *n1 = new_tree_node(406759, n1a, n1t);
bst_insert(root, n1);
And this is the insert() function:
void bst_insert(struct TreeNode *tree_node, struct TreeNode *new_node) {
if (new_node->key < tree_node->key) {
//If the key is smaller -> insert left
if (tree_node->left == NULL) {
//There is no left node yet
tree_node->left = new_node;
return;
} else
bst_insert(tree_node->left, new_node); //There is a node -> pass it on
}
else {
//The key is larger -> right
if (tree_node->right == NULL) {
//There is no left node yet
`enter code here`tree_node->right = new_node;
return;
} else
bst_insert(tree_node->right, new_node); //There is a node -> pass it on
}
}

Valgrind Error "Invalid write of size 4" C

I'm programming in C, and when I use Valgrind to check memory errors, the next error has shown:
==9756== Invalid write of size 4
==9756== at 0x40164D: main (flowTracker.c:294)
==9756== Address 0x24 is not stack'd, malloc'd or (recently) free'd
The line 294 of flowTracker.c is the next:
tabla_hash[clave_hash]->contador++;
And the declaration of tabla_hash is:
#define TAMANHO_TABLA 1048576
typedef struct{
int tiempo_ini;
int tiempo_ult;
uint8_t quintupla[13];
int num_bytes;
int num_SYN;
int num_ACK;
int contador;
double pack_s;
double bits_s;
} FlujoIP;
FlujoIP *tabla_hash[TAMANHO_TABLA];
As 4566976 pointed out, tabla_hash[clave_hash] is (probably) NULL. That's just a guess, as you haven't provided an MCVE which reproduces the issue without us having to fill in the blanks or fix compiler errors...
It seems to me as though you probably meant to declare tablahash like so: FlujoIP tabla_hash[TAMANHO_TABLA]; (though, wow! That's a huge array)... and you should then be able to change -> to . like so: tabla_hash[clave_hash].contador++;
Alternatively, if you were to precede the offending statement with if (tablahash[clave_hash] == NULL) { tablahash[clave_hash] = malloc(sizeof tablahash[clave_hash][0]); } or something, that might also be appropriate... Don't forget to free all of the items within your huge array.

Valgrind, "uninitialized value(s)" error

In my C program, I'm allocating memory using malloc() which does, in contrast to calloc(), not initialize the memory and it might still contain garbage. Mostly, in context of the allocation, I do not make any changes to the memory allocated by malloc(). (For example in a function to initialize a struct that contains a buffer, I do not make changes to the buffer's memory, but later on).
Valgrind gives me a lot of theese errors:
Conditional jump or move depends on uninitialised value(s)
Use of uninitialised value of size 4
I am sure to never read from memory that was not initialized in these cases.
Should I ignore them or is it better to initialize the memory on allocation? In case I should ignore them, how can I deactivate this error message in Valgrind?
Example 1:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x408EB8E: vfprintf (vfprintf.c:1624)
==4253== by 0x4093C2E: printf (printf.c:35)
==4253== by 0x40624D2: (below main) (libc-start.c:226)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048938: gk_StreamBufferNode_init (stream.c:101)
==4253== by 0x8048D0D: gk_Stream_bufferWriteProc (stream.c:252)
==4253== by 0x8048665: main (main.c:21)
Code:
int gk_StreamBufferNode_init(gk_StreamBufferNode* node, int buffer_size,
gk_AllocProc malloc) {
node->buffer = malloc(buffer_size); // line 101
if (node->buffer == NULL) {
return GKIT_FAILEDALLOC;
}
node->next = NULL;
return GKIT_NOERR;
}
Example 2:
==4253== Conditional jump or move depends on uninitialised value(s)
==4253== at 0x402DA39: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048C6E: gk_Stream_bufferWriteProc (stream.c:230)
==4253== by 0x8048665: main (main.c:21)
==4253== Uninitialised value was created by a heap allocation
==4253== at 0x402BE68: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4253== by 0x8048CE0: gk_Stream_bufferWriteProc (stream.c:248)
==4253== by 0x8048665: main (main.c:21)
Code:
/* ... */
int available_bytes = binfo->buffer_size - bnode->filled;
int bytes_to_go = size * count;
int offset = 0;
int node_offset = 0;
gk_StreamBufferNode* new_node;
void* destination = NULL;
void* source = NULL;
while (bytes_to_go > 0) {
destination = bnode->buffer + bnode->filled + node_offset;
source = buffer + offset;
if (available_bytes > bytes_to_go) {
memcpy(destination, source, bytes_to_go); // line 230
bnode->filled += bytes_to_go;
offset += bytes_to_go;
node_offset = bytes_to_go;
bytes_to_go = 0;
}
else {
memcpy(destination, source, available_bytes);
offset += available_bytes;
node_offset = 0;
bytes_to_go -= available_bytes;
bnode->filled += available_bytes;
#ifdef DEBUG
assert(bnode->filled == bnode->buffer_size);
#endif // DEBUG
// Allocate a new buffer node.
new_node = (gk_StreamBufferNode*) malloc(sizeof(gk_StreamBufferNode)); // line 248
if (new_node == NULL) {
return GKIT_FAILEDALLOC;
}
int success = gk_StreamBufferNode_init(new_node, binfo->buffer_size,
malloc);
if (success <= GKIT_ERROR) {
free(new_node);
return GKIT_FAILEDALLOC;
}
bnode->next = new_node;
bnode = new_node;
available_bytes = binfo->buffer_size;
}
}
In both cases you just allocate memory without initializing it. The easiest way is to use calloc instead of malloc to zero it out. This may be a good strategy for simple cases, e.g if you later use a buffer as a string that is to be printed. For more complicated use cases assign values to the individual fields, or even better if you have C99 assign the whole structure from a compound literal:
toto * t = malloc(sizeof(*t));
*t = (toto){ 0 };
Your code should not be expecting uninitialized memory to contain any value, so having conditional jumps dependent on these shows serious problems.
You should either be initializing the memory (to some known value, eg. 0), or not refer to its contents unless they have been initialized.

Resources