Memory leak after shrinkage with realloc - c

I don't know, what has happened to the formatting, but I can't mark selected chunks as code with Ctrl+K. SORRY FOR THAT
I use gcc with flags as a compiler and run valgrind with:
valgrind --leak-check=full -q --error-exitcode=1
I am trying ti write a calculator for addition and subtraction. The numbers are stored in an array of the fixed size, written in 10000 numerical system: each element of array has an allocated memory for four digits:
#include <stdlib.h>
#include <limits.h>
#define ELEMENTS 8
#define NUM_INT 4 //Number of digits
typedef struct numb {
int* digits;
int how_many; //How many cells with 4 digits
} numb;
void create(numb** tab) {
*tab = realloc(*tab, ELEMENTS * sizeof(**tab));
for (int i = 0; i < ELEMENTS; i++) {
numb cell;
cell.digits = calloc(NUM_INT, sizeof (*cell.digits));
cell.how_many = 1;
(*tab)[i] = cell; // Put in original array.
}
(*tab)[ELEMENTS-2].digits[0] = -1; // Don't bother about the values
(*tab)[ELEMENTS-1].digits[0] = 1;
}
The valgrind shows a problem in two functions:
addition of two structures
//help function
int simple_add(int w, int m, int* p) {
int number;
int result = w + m + *p;
if (result >= 10000) {
*p = division(result); //division by multiplication while p*i<=10000
number = result - 10000*(*p);
} else {
number = result;
*p = 0;
}
return number;
}
//problematic
void add(numb* a, numb* b) {
numb *big;
numb *small;
if (a->how_many != b->how_many) {
small = min(a, b); //simple min and max functions, not written for clarity
big = max(a, b);
} else {
big = a;
small = b;
}
int left = 0;
int i = 0;
while (i < small->how_many) {
big->digits[i] = simple_add(big->digits[i], small->digits[i], &left);
i++;
}
while (left != 0) {
if (i == big->how_many) {
if ((size_t)i*NUM_INT*sizeof(int) >= sizeof(big->digits)) {
int size;
if ((size_t)i*NUM_INT*sizeof(int) + 2 >= INT_MAX) size = INT_MAX-1;
else size = (size_t)i*NUM_INT*sizeof(int) + 2;
big->digits = realloc(big->digits, size);
}
big->digits[i++] = left;
big->how_many++;
pom = 0;
} else {
big->digits[i] = simple_add(big->digits[i], 0, &left);
i++;
}
}
*a = *big;
}
set the value to 0
void clear(numb* a) {
a->digits = realloc(a->digits, NUM_INT*sizeof(int));
a->digits[0] = 0;
a->how_many = 1;
}
For small numbers it works fine for valgrind, without errors. However, as the values in test files get bigger, I get stackovflow/segmentation fault:
I present three types of errors from valgrind to reduce the amount of clutter:
Just before segmenation fault:
Invalid free() / delete / delete[] / realloc()
==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==13932== by 0x10A084: clear (address)
==13932== by 0x10A298: interpreter (in address)
==13932== by 0x10A375: game (in address)
==13932== by 0x10A436: main (in address)
Address 0x4a3ebc0 is 0 bytes inside a block of size 34 free'd
==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==13932== by 0x10A084: clear (in /address)
==13932== by 0x10A298: interpreter (in address)
==13932== by 0x10A375: game (in /address)
==13932== by 0x10A436: main (in /address)
==13932== Block was alloc'd at ==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826) ==13932== by 0x10943A: add (in /address)
==13932== by 0x10A1F8: interpreter (in address)
==13932== by 0x10A375: game (in address)
Invalid write of size 4
==13932== at 0x10A096: clear (in /address)
==13932== by 0x10A298: interpreter (in /address)
==13932== by 0x10A375: game (in /address)
==13932== by 0x10A436: main (in /address)
==13932== Address 0x0 is not stack'd, malloc'd or (recently) free'd
Mostly this is invalid write or read; invalid free appears only once. I didn't want to clutter the post with the chunk of all messages, but if you need to, I can paste it.
Array from create is freed after the program.
Please, I would appreciate your suggestions. For small numbers it works, thus it is harder for me to track what is going on if we go to big ones. The numbers are supposed to be <INT_MAX
EDIT
I have run some tests and have found error in add and clear, but I don't know, how to fix it yet.
Issue:
I have to variables and add the using add()
the first one is zero, thus it has only one cell [0] ::= num a
the second one is over 10000 (for example: 16547), thus it has two cells [6547][1] ::= num b
**Where I have found the problem"
add b to a; a= 0; b = 16547
clear a //supposed to be 0
print out b <- I got an error
==52293== Invalid read of size 4
==52293== at 0x10CC75: print_a_number (call5.c:355)
==52293== by 0x10D027: interpreter (call5.c:397)
==52293== by 0x10D35F: rozgrywka (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== Address 0x58c6804 is 4 bytes inside a block of size 34 free'd
==52293== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==52293== by 0x10CD65: clear (call5.c:367)
==52293== by 0x10D215: interpreter (call5.c:426)
==52293== by 0x10D35F: rozgrywka (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== Block was alloc'd at
==52293== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==52293== by 0x10B887: add (call5.c:117)
==52293== by 0x10D115: interpreter (call5.c:406)
==52293== by 0x10D35F: game (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
As we can remember, clear realloced the size and left the first cell. However, the other cells are freed. It seems as if the second cell was lost [1], but I do not understand that, if I have assigned the value to the pointer *a in add.

Related

How do I fix these memory leaks in C?

I am working on a function which allocates memory into an array, and then I free it later. Oddly enough, valgrind is giving me this error:
==93== HEAP SUMMARY:
==93== in use at exit: 11,160 bytes in 2,232 blocks
==93== total heap usage: 44,310 allocs, 42,078 frees, 1,632,230 bytes allocated
==93==
==93== 11,160 bytes in 2,232 blocks are definitely lost in loss record 1 of 1
==93== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==93== by 0x10976F: FillHashMap (in /mnt/c/Users/Jordan/Documents/GitHub/flwg/flwp)
==93== by 0x1092F1: main (in /mnt/c/Users/Jordan/Documents/GitHub/flwg/flwp)
==93==
==93== LEAK SUMMARY:
==93== definitely lost: 11,160 bytes in 2,232 blocks
==93== indirectly lost: 0 bytes in 0 blocks
==93== possibly lost: 0 bytes in 0 blocks
==93== still reachable: 0 bytes in 0 blocks
==93== suppressed: 0 bytes in 0 blocks
==93==
==93== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Dr. Memory is giving me a similar error:
Error #1: UNADDRESSABLE ACCESS: reading 0x0000000000000000-0x0000000000000008 8 byte(s)
# 0 testing [C:/Users/Jordan/Documents/GitHub/flwg/FLWP-2.c:120]
# 1 main [C:/Users/Jordan/Documents/GitHub/flwg/FLWP-2.c:105]
Note: #0:00:01.195 in thread 14704
Note: instruction: mov (%rax) -> %rax
The strcmp line of code is what causes it to break with Dr. Memory, although valgrind says I have issues even if I don't call this particular method.
void testing(struct wordConnections *header){
header = header->nextRow;
while(strcmp(header->word, "berk") != 0){
header = header->nextRow;
if(header == NULL){
printf("Failed");
return;
}
}
}
The code that runs is (the value and significance of numLetters + 1 is it is the length of the char* stored in the wordStorage, the value of numLetters is 4):
char** FillHashMap(struct wordConnections **(*HashMap)){
int h = 0;
/* The Amount of words in each file, File 1, 2, 3 */
int totalWordQuantity[3] = {132, 7420, 19829};
/*the word that we test, we add by two because first 4: word, 5th: \n, 6th: \0*/
char word[numLetters + 1];
/*how many times we've changed the character*/
int letterSpot = 0;
/*the character that goes through the file*/
char c;
FILE *flwd = OpenFile();
/* is it the first word of the line */
int wordCount = 0;
int isFirst = 1;
char p = fgetc(flwd);
c = p;
/* So, this is a temporary word, who will store the row, so all of its category folks will be contained within it */
char* rowWord = malloc(sizeof(char) * (numLetters + 1));
/*This stores all of the words*/
char** wordStorage = (char**)calloc(totalWordQuantity[numLetters - 2], sizeof(char*) * (numLetters + 1));
int i = 0;
/* First, take the character */
while((c = p) != EOF){
p = fgetc(flwd);
/* Add the character to the word */
word[letterSpot] = c;
/* Allows the letter spot to find the next place into the word */
letterSpot++;
/* Determines if the character is the placement immediately after the word */
if((c == ' ' && p != '\n') || c == '\n'){
letterSpot = 0;
/* Throws in the \0, converting into a string */
word[numLetters] = '\0';
wordStorage[wordCount] = malloc(sizeof(char) * (numLetters + 1));
h++;
strcpy(wordStorage[wordCount], word);
/* Determine if it's the first word */
if(isFirst == 1){
strcpy(rowWord, word);
/* Throw it in as a row */
AddRow2DLL(wordStorage[wordCount],
HashMap[FirstHashFunction(word[0])/*First Letter*/]
[SecondHashFunction(word)]/*First Vowel*/);
}
/* If it's not the first word */
else {
AddColumn2DLL(wordStorage[wordCount],
HashMap[FirstHashFunction(rowWord[0])/*First Letter*/]
[SecondHashFunction(rowWord)]/*First Vowel*/);
}
if(c == ' '){
isFirst = 0;
}
if(c == '\n'){
isFirst = 1;
}
wordCount++;
}
c = p;
}
free(rowWord);
fclose(flwd);
return wordStorage;
}
The hash map works fine, this is the method that causes the issues, without it, there are no memory leaks.
Later in the code, I free the wordStorage array with this method:
void FreeWordStorage(char** wordStorage){
int f = 0;
/* The Amount of words in each file, File 1, 2, 3 */
int totalWordQuantity[3] = {132, 7420, 19829};
int i;
for(i = 0; i < totalWordQuantity[numLetters - 2]; i++){
free(wordStorage[i]);
f++;
}
free(wordStorage);
}
I've tried all sorts of things to fix it. Oddly enough, when I check it with integers, I'm allocating and freeing the same amount of data.
Any help would be greatly appreciated. Thank you!
Valgrind's analysis indicates that the leaked memory was allocated by a bunch of malloc() calls by function FillHashMap(), and the only plausible candidate for those is this:
wordStorage[wordCount] = malloc(sizeof(char) * (numLetters + 1));
Function FreeWordStorage() appears to be correct for freeing the data allocated by FillHashMap(), so if some allocations are going unfreed then there are two main possibilities:
The pointer value returned by FillHashMap() is not later passed to FreeWordStorage(). The latter function might not be called at all on the code path that is being exercised, or perhaps a modified or outright wrong pointer is being passed to it.
Or,
Some or all of the pointers recorded in the allocated block returned by FillHashMap() are modified after being recorded, so that when it is called, FreeWordStorage() is ineffective at freeing the allocated memory.
Either one of those could be consistent with Dr. Memory's diagnostic, but whichever scenario applies, it does not appear to play out in the code presented in the question. I am reasonably confident that your pointers are being mangled somewhere else in the program.

"Invalid read of size 4" when trying to realloc memory

I'm writing a Snake game as the first "serious" project in C. But when I try to grow the snake, program crashes with SEGFAULT error.
So, i tried to run the game in Valgrind, and got this:
==11312== 30 errors in context 7 of 7:
==11312== Invalid read of size 4
==11312== at 0x10969E: collide (game.c:238)
==11312== by 0x108FBD: main (game.c:120)
==11312== Address 0x5897c60 is 0 bytes inside a block of size 40 free'd
==11312== at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312== by 0x109724: snake_grow (game.c:250)
==11312== by 0x108F7D: main (game.c:113)
==11312== Block was alloc'd at
==11312== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11312== by 0x109278: start (game.c:159)
==11312== by 0x108EC0: main (game.c:91)
==11312==
==11312== ERROR SUMMARY: 80 errors from 7 contexts (suppressed: 0 from 0)
As I can suggest, I did realloc wrong and that is why the game crashes. So, the problem should be here:
void snake_grow(snake_t *snake){
snake->length++;
snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
snake->end = snake->body + snake->length - 1;
snake->end->x = snake->prev_x;
snake->end->y = snake->prev_y;
}
Or maybe I just use pointer in fuction wrong?
bool collide(snake_t *snake, block map[MAXY][MAXX]){
bool ret = FALSE;
if(map[snake->head->y][snake->head->x].collision == COLLIDABLE){
ret = TRUE;
}
for(int i = 1; i < snake->length; i++){
if(snake->body[i].x == snake->head->x){
if(snake->body[i].y == snake->head->y){
ret = TRUE;
}
}
}
return ret;
}
Strange, but I can't find anything similar to my problem. But maybe I just didn't understand solutions.
Accidentally, when I tried to make minimal reproducible example and debug, as it was advised by WhozCraig, I solve this problem.
void snake_grow(snake_t *snake){
snake->length++;
snake->body = realloc(snake->body, sizeof(snake->body[0]) * (snake->length));
snake->end = snake->body + snake->length - 1;
snake->end->x = snake->prev_x;
snake->end->y = snake->prev_y;
}
This function, besides reallocating memory, sets new address for snake->end. But there is also the snake->head, which after realloc points to the same address. So, everything that I needed to do is just set snake->head to new address.
snake->head = snake->body;

What's the correct use of free with returned pointers?

I have wrote a small example problem to learn about memory allocation and freeing this memory (to protect from memory leaks):
#include <stdlib.h>
long* foo(char str[]) {
long *nums;
nums = calloc(2,sizeof(long));
//something is happening depending on what's inside the char[]
nums[0] = 57347534;
nums[1] = 84757;
return nums;
}
int main() {
char str1[400] = "This is a test";
long* retValue = foo(str1);
//some lines of checking content of "retValue"
char str2[400] = "This is another test";
retValue = foo(str2);
//some more lines of checking content of "retValue"
char str3[400] = "This is a final test";
retValue = foo(str3);
//again some more lines of checking content of "retValue"
free(retValue);
}
So in my main function, I am using three char arrays which I will pass to my function. This function has a num pointer of long values where am callocing two of them. Then I am just calculating some numbers according to the content in str[] and return nums.
My questions about this are:
How do I free the memory I used for nums? Because I cannot free it before I use it for return.
Is it right to free the retValue in the last line there?
Am I right that I do not need to free my char arrays, because they are not dynamic?
Thanks for your answers, that would help me more safely use pointers!
You need to call free before every new assignment to retValue (if the previous assignment came from malloc, calloc or realloc). Otherwise you will have memory leaks.
Every allocation must be matched by a free, plain and simple.
A good way to answer questions about memory allocation and use is to use a memory checker - I'll use Valgrind:
gcc-8 -std=c11 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds 50627661.c -o 5062766
50627661.c: In function ‘foo’:
50627661.c:3:16: warning: unused parameter ‘str’ [-Wunused-parameter]
long* foo(char str[]) {
~~~~~^~~~~
valgrind -q --leak-check=full ./50627661
==14785== HEAP SUMMARY:
==14785== in use at exit: 32 bytes in 2 blocks
==14785== total heap usage: 3 allocs, 1 frees, 48 bytes allocated
==14785==
==14785== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2
==14785== at 0x4C2EBA5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14785== by 0x10867F: foo (50627661.c:5)
==14785== by 0x1086F6: main (50627661.c:18)
==14785==
==14785== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==14785== at 0x4C2EBA5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==14785== by 0x10867F: foo (50627661.c:5)
==14785== by 0x108758: main (50627661.c:24)
This shows that of the three allocations we made, we only freed one of them - the other two leaked.
If you do not want to clutter your calling code with free, the alternative is to pass to the callee an array mangaged by the caller:
long foo(char str[], long *nums, int size) {
if (size < 2) { // passed array must be at least 2 long
return -1;
}
//something is happening depending on whats inside the char[]
nums[0] = 57347534;
nums[1] = 84757;
return 2; // returns used size (or -1 for error)
}
int main() {
long retValue[2];
char str1[400] = "This is a test";
if (-1 == foo(str1, retValue, 2)) {
// process error condition
}
//some lines of checking content of "retValue"
char str2[400] = "This is another test";
if (-1 == foo(str2, retValue, 2)) {
// process error condition
}
//some more lines of checking content of "retValue"
char str3[400] = "This is a final test";
if (-1 == foo(str3, retValue, 2)) {
// process error condition
}
//again some more lines of checking content of "retValue"
//free(retValue); no need for free since nothing was allocated...
return 0;
}

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

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.

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