Valgrind - uninitialized value - c

The following code is part of a larger program, so I created a test file to try to isolate the problem. The code is working fully as intended, but it is throwing a valgrind error. From my understanding, I think it is most likely referring to *inputStr.
Valgrind error message:
==2807== Conditional jump or move depends on uninitialised value(s)
==2807== at 0x3156434819: ____strtol_l_internal (in /lib64/libc-2.5.so)
==2807== by 0x3156431BD1: atoi (in /lib64/libc-2.5.so)
==2807== by 0x400818: getInt (test.c:50)
==2807== by 0x4008B5: main (test.c:70)
==2807== Uninitialised value was created by a stack allocation
==2807== at 0x400668: getInt (test.c:13)
==2807==
==2807== Conditional jump or move depends on uninitialised value(s)
==2807== at 0x315643482F: ____strtol_l_internal (in /lib64/libc-2.5.so)
==2807== by 0x3156431BD1: atoi (in /lib64/libc-2.5.so)
==2807== by 0x400818: getInt (test.c:50)
==2807== by 0x4008B5: main (test.c:70)
==2807== Uninitialised value was created by a stack allocation
==2807== at 0x400668: getInt (test.c:13)
==2807==
==2807== Use of uninitialised value of size 8
==2807== at 0x31564348A8: ____strtol_l_internal (in /lib64/libc-2.5.so)
==2807== by 0x3156431BD1: atoi (in /lib64/libc-2.5.so)
==2807== by 0x400818: getInt (test.c:50)
==2807== by 0x4008B5: main (test.c:70)
==2807== Uninitialised value was created by a stack allocation
==2807== at 0x400668: getInt (test.c:13)
My code: Parses input command via stdin (e.g. "i 5"), the "i" would be used in a menu switch (but that code is removed), then calls getInt(), which starts scanning the inputStr at index 1 to parse the integer value from the inputStr. I have marked error lines 13, 50, and 70 as comments for clarity.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int getInt(char *inputStr, int *value, int *i) { // <-----line 13
char num[5];
int ctr = 0;
/* Skip whitespace */
while (!isdigit(*(inputStr+(*i))) && *(inputStr+(*i)) != '-') {
/* Input with only command letter and no integer value */
if (*(inputStr+(*i)) == '\n') {
//printError(-1);
return -1;
}
/* Input has invalid characters after command letter */
if (!isspace(*(inputStr+(*i)))) {
//printError(-2);
return -2;
}
(*i)++;
}
if (*(inputStr+(*i)) == '-') {
num[ctr++] = *(inputStr+(*i));
(*i)++;
}
/* Copy number characters to another array */
while (isdigit(*(inputStr+(*i)))) {
num[ctr++] = *(inputStr+(*i));
(*i)++;
}
/* Check if unwanted characters terminated the while loop above */
if (!isspace(*(inputStr+(*i)))) {
//printError(-2);
return -2;
}
/* Convert number characters to integer */
*value = atoi(num); // <----line 50
//printf("Positive Integer: num = %s, value = %d\n",num, value);
return 0;
}
int main () {
int value, i, int1;
char *inputStr;
size_t sizeInput = 10;
inputStr = malloc(sizeof(char) * sizeInput);
for (i = 0; i < sizeInput; i++)
inputStr[i] = '\0';
value = 0;
i = 1; //starting position for parsing number
getline(&inputStr, &sizeInput, stdin);
int1 = getInt(inputStr, &value, &i); // <---line 70
printf ("%d\n", value);
free(inputStr);
return 0;
}
Appreciate the help.
[Resolved] thanks to #JonathanLeffler. Added num[ctr] = '\0'; one line above the atoi() conversion. Now error free.

You have multiple errors:
getline return new memory by first parameter if the buffer is not large enough to hold the line, so you don't need allocate memory for inputStr, but you have to free it. You can just set inputStr to NULL, the getline will return new memory.
when you call function getInt, variable 'i' is initialize as 1; C/C++ array index starts with 0, so it should be 0, I don't know if you intend to pass 1 as the first.
in function getInt, the variable 'num' is not initialized if the while and if block are not excectuted, you can change it to:
char num[5] = {0};
Also in function getInt, no code to check if the string inputStr is already ended, so your loops may cause access violation.

Related

Memory leak after shrinkage with realloc

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.

Valgrind: Conditional jump depends on uninitialised value(s) created by a stack allocation

When debugin my code, I'm getting a series of strange errors in Valgrind. The errors are all of the same type: "Conditional jump or move depends on uninitialised value(s) at ... Uninitialised value was created by a stack allocation at ...".
Example of valgrind output:
==153367== Thread 6:
==153367== Conditional jump or move depends on uninitialised value(s)
==153367== at 0x14B393: serializeNewAnnounce (topology_discovery.c:1146)
==153367== by 0x1494A2: upon_AnnounceTimer (topology_discovery.c:360)
==153367== by 0x148D87: topology_discovery_main_loop (topology_discovery.c:189)
==153367== by 0x49EB608: start_thread (pthread_create.c:477)
==153367== by 0x4B27102: clone (clone.S:95)
==153367== Uninitialised value was created by a stack allocation
==153367== at 0x14AB00: serializeNewAnnounce (topology_discovery.c:1076)
==153367==
==153367== Conditional jump or move depends on uninitialised value(s)
==153367== at 0x14B3CC: serializeNewAnnounce (topology_discovery.c:1204)
==153367== by 0x1494A2: upon_AnnounceTimer (topology_discovery.c:360)
==153367== by 0x148D87: topology_discovery_main_loop (topology_discovery.c:189)
==153367== by 0x49EB608: start_thread (pthread_create.c:477)
==153367== by 0x4B27102: clone (clone.S:95)
==153367== Uninitialised value was created by a stack allocation
==153367== at 0x14AB00: serializeNewAnnounce (topology_discovery.c:1076)
At a frist glance, this error seems to indicate that I forgot to initialize some memory.
However, up verifying several times, I can't find where exactly is the source of these errors.
The code is huge and with several functions, so I filtered only the important parts:
...
148 topology_discovery_state* state = malloc(sizeof(topology_discovery_state));
149 memset(state, 0, sizeof(topology_discovery_state));
...
260 state->neighbors = double_list_init(); // neighbors is a malloc and initializes head as NULL
...
... // The following code is within a single function, the previous is on another function
...
1047 unsigned int horizon = state->proto_args.horizon;
...
1050 unsigned char ptrs[horizon+1];
1051 memset(ptrs, 0, sizeof(ptrs));
...
1076 for(double_list_item* current_item = state->neighbors->head; current_item; current_item = current_item->next) {
1077 neighbor* current_neigh = (neighbor*) current_item->data;
...
1106 for(int h = 0; h <= horizon; h++) {
1107 ptrs[h] = levels[h]->size + ptrs[h-1];
1108 }
...
1145 int processed = 0;
1146 for(int h = 0; h <= horizon; h++) {
1147 int level_size = ptrs[h];
1148 int level_start = h == 0 ? 0 : ptrs[h-1];
1149 for(int node = level_start; node < level_size; node++) {
...
Only state is not a local variable and is passed as a parameter, the rest is all local to the same function.
At line 1107, in the first iteration, ptrs get index -1. Since in C array is actually a memory location and index interprete as pointer arithmetic, the result is access to the memory location that is one byte before ptrs, which is of course not initialized.

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.

C Valgrind - Conditional jump depends on unitialitialised value

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().

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