C Valgrind - Conditional jump depends on unitialitialised value - c

i want to repair one error..
Valgrind says me this:
==9203== 1 errors in context 1 of 1:
==9203== Conditional jump or move depends on uninitialised value(s)
==9203== at 0x4C2D64A: strncat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9203== by 0x400970: newSpeak (main.c:39)
==9203== by 0x400A62: main (main.c:74)
==9203==
--9203--
--9203-- used_suppression: 2 dl-hack3-cond-1
==9203==
==9203== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Here is my function newSpeak()
int velikost = 0, i = 0, delka = 0;
char * textNovy = NULL;
i = 0;
while (text[i] != '\0') {
delka++;
i++;
}
textNovy = (char*)malloc(sizeof(char));
for (i = 0; i < delka; i++) {
textNovy = (char*)realloc(textNovy, ((i+1)+velikost)*sizeof(char) );
strncat(textNovy, text+i, 1);
}
return textNovy;
value text is given to function from main.
Problem is somewhere in strncat
Thans you!! Lukas

You never initialize the contents of textNovy, yet you concatenate on to the end of it. This leads to the error you are seeing from valgrind.
You need at least:
textNovy[0] = '\0';
(or an equivalent) after the malloc().

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;

A random character showing up at the end of a C array

I have the code:
else if ((strtolnum=(strtol(&oldline[b+1],NULL,10)))>0)
{
char* excl = malloc(3*sizeof(char));
excl[0]=oldline[b];
excl[1]=oldline[b+1];
for (int j = 0; j<strtolnum; j++)
{
llist=llist->nextcmd;
}
struct token *p1;
struct token *save1 = llist->cmmd;
char *arra1 = malloc(sizeof(char));
memset(arra1, '\0', 1);
for (p1 = llist->cmmd; p1 != NULL; p1 = p1->next) {
arra = realloc(arra1, strlen(arra1)+strlen(p1->text)+2);
strcat(arra, p1->text);
if (p1->next!=NULL)
{
strcat(arra1, " ");
}// printing token and type
}
printf("%s excl\n", excl); //Line 137
oldline=strreplace(oldline,excl,arra1); //Line 138
llist->cmmd=save1;
for (int j = 0; j<(f-strtolnum); j++)
{
llist=llist->nextcmd;
}
*status=1;
size_t a = sizeof(excl);
memset(excl,'\0', a);
}
What the code should accomplish is get the first integer of a line which is preceded by an exclamation part, such as !3, and puts it in excl (and then do other stuff which is working perfectly fine).
However, when I run the loop more than once, I find that excl often has a random character at the end, such as when it shows up as "!3e" when I try to printf it. Valgrind shows the following errors:
==24878== Conditional jump or move depends on uninitialised value(s)
==24878== at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so)
==24878== by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so)
==24878== by 0x40130F: hExpand (Lex1.c:137)
==24878== by 0x400B6B: main (mainLex.c:27)
==24878==
==24878== Conditional jump or move depends on uninitialised value(s)
==24878== at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24878== by 0x4020D7: strreplace (Lex1.c:562)
==24878== by 0x40132C: hExpand (Lex1.c:138)
Apparently, excl is unititialized after the loop goes through once. What is wrong?
For additional information, cmmd is a data structure of type token, and llist is a global static data structure containing tokens.
You haven't null terminated the excl string; malloc() returns random garbage. You might think about adding:
excl[2] = '\0';
You also trample way out of bounds with:
size_t a = sizeof(excl);
memset(excl,'\0', a);
You assign either 4 or 8 (32-bit or 64-bit) to a, and then write over that many bytes, but you only allocated 3 bytes for excl.

How to copy arrays of arrays in C? (array of string to another array of string)

I'm doing Zed Shaw's Learn C The Hard Way course. On exercise 11, in the extra-credit question #2, he askes:
Make these loops count backward by using i-- to start at argc and count down to 0. You may have to do
some math to make the array indexes work right.
Use a while loop to copy the values from argv into states.
I try:
#include <stdio.h>
int main(int argc, const char *argv[]){
int i = argc - 1;
while(i >= 0){
printf("arg %d: %s\n", i, argv[i]);
i--;
}
char *states[] = {
"California", "Oregon",
"Washington", "Texas"
};
int num_states = 4;
i = num_states - 1;
while( i >= 0){
printf( "state %d, %s\n", i, states[i]);
i--;
}
i = 0;
while(i < argc && i < num_states){
int j = 0;
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
states[i][j] = '\0';
}
i = num_states - 1;
while( i >= 0){
printf( "state %d, %s\n", i, states[i]);
i--;
}
return 0;
}
I get a Segmentation Fault. I understand that you can't copy arrays in C, that they are const pointer or something similar (or so I read). That's why I try to copy character by character:
while(i < argc && i < num_states){
int j = 0;
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
states[i][j] = '\0';
}
Yet it doesn't work. How should I do this? The compiler gives me this warning when I compile:
$ make ex11
cc -Wall -g ex11.c -o ex11
ex11.c: In function ‘main’:
ex11.c:26:28: warning: operation on ‘j’ may be undefined [-Wsequence-point]
I don't get why it says that j is undefined. valgrind says this:
$ valgrind ./ex11 this is a test
==4539== Memcheck, a memory error detector
==4539== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4539== Using Valgrind-3.8.0 and LibVEX; rerun with -h for copyright info
==4539== Command: ./ex12 this is a test
==4539==
arg 4: test
arg 3: a
arg 2: is
arg 1: this
arg 0: ./ex11
state 3, Texas
state 2, Washington
state 1, Oregon
state 0, California
==4539==
==4539== Process terminating with default action of signal 11 (SIGSEGV)
==4539== Bad permissions for mapped region at address 0x400720
==4539== at 0x4005F1: main (ex11.c:26)
==4539==
==4539== HEAP SUMMARY:
==4539== in use at exit: 0 bytes in 0 blocks
==4539== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==4539==
==4539== All heap blocks were freed -- no leaks are possible
==4539==
==4539== For counts of detected and suppressed errors, rerun with: -v
==4539== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Segmentation fault
[EDIT 1]
A switched my code for this
int i = 0;
while( i < argc && i < num_states ){
states[i] = argv[i];
i++;
}
It does work, but the compiler gives me a warning. Also, I realized after posting this question that my previous:
while( (states[i][j++] = argv[i][j++]) != '\0' ){
i++;
}
Is just plain wrong. Because the j++ is executed twice per loop, and that i++ should be outside that loop in the outer loop. And also as mentioned in the comment below, that the byte-by-byte copy that I try to do using array of arrays doesn't work because I actually have array of pointers.
That said, is there a way I could do this without having the compiler's warning?
One problem (the one that causes the SEGV) is that while states is an array of char *, you're initializing it with a bunch of string literals (which are const char *). So you should at least be getting a warning on that line. This comes to bite you when you try to write into the string constant (which is in read-only memory).
Now if you really want to copy the strings from argv to states one byte at a time (rather than just copying pointers -- eg states[i] = argv[i]), you need to make sure that states[i][j] is writable. You could do that by making states an array of arrays of chars, instead of an array of pointers to chars:
char states[][16] = {
"California", "Oregon",
"Washington", "Texas"
};
Of course, these are fixed size arrays, so you need to worry about overflowing them, but you already had the problem of overflowing the states array itself.
I just finished that exercise myself, and was doing some more research on copying after having already completed it (as Zed suggested). Here's what I did, without a problem.
i = 0;
num_states = NELEMS(states);
while(i < argc && i <= num_states) {
states[i] = argv[i];
i++;
}

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