Reputation: 937
I am calling a bash script from my c code, which lets say generate a text file and returns the link of it. Thats why I use popen instead of system, because I need the output stream of it So I parse for the link and want to store it in a string in C. This is how I do it:
#define LINK_KEY "FILE LINK:"
-------------------
char *the_link;
int is_set = 0;
FILE *call_script;
call_script = popen("/location/of/script/script.sh", "r");
if (call_script == NULL) {
fprintf(stderr, "Could not script. Aborting...\n");
exit(EXIT_FAILURE);
}
char *line;
int line_len = 128;
line = malloc(sizeof(char)*line_len);
while (fgets(line, line_len, call_script) != NULL) {
int line_len = strlen(line);
if (line[line_len-1] == '\n') {
if (strstr(line, LINK_KEY)) {
int j;
for (j = 0; j < strlen(line); j++) {
if (line[j] == ':') {
is_set = 1;
break;
}
}
if (is_set) {
int link_len = line_len - j - 1;
if (link_len <= 0) {
fprintf(stderr, "Error in finding file. Aborting...\n");
exit(EXIT_FAILURE);
}
the_link = malloc(sizeof(char) * (link_len +1)); // <=== here is where valgrind complains
strncpy(the_link, &line[j + 1], link_len - 1);
the_link[link_len] = '\0';
}
}
} else {
line_len*=2;
line = realloc(line, sizeof(char)*line_len;
}
}
if (!is_set) //.... throw error and abort
And I dont know why Valgrind complains that the variable is not initialised:
==7196== Uninitialised value was created by a heap allocation
==7196== at 0x4A0887C: malloc (vg_replace_malloc.c:270)
==7196== by 0x4018A7: main (jumping_al.c:172)
Upvotes: 0
Views: 264
Reputation: 320
I found the cause of this issue. I copied the above code, compiled and executed valgrind in my machine. Valgrind provided output as definite leak "definitely lost: 128 bytes in 1 blocks"
==5121== HEAP SUMMARY:
==5121== in use at exit: 300 bytes in 2 blocks
==5121== total heap usage: 2 allocs, 0 frees, 300 bytes allocated
==5121==
==5121== Searching for pointers to 2 not-freed blocks
==5121== Checked 52,360 bytes
==5121==
==5121== 128 bytes in 1 blocks are definitely lost in loss record 1 of 2
==5121== at 0x400682F: malloc (vg_replace_malloc.c:236)
==5121== by 0x804865C: main (in /home/userm/code/a3.out)
==5121==
==5121== LEAK SUMMARY:
==5121== definitely lost: 128 bytes in 1 blocks
==5121== indirectly lost: 0 bytes in 0 blocks
==5121== possibly lost: 0 bytes in 0 blocks
==5121== still reachable: 172 bytes in 1 blocks
==5121== suppressed: 0 bytes in 0 blocks
==5121== Reachable blocks (those to which a pointer was found) are not shown.
==5121== To see them, rerun with: --leak-check=full --show-reachable=yes
==5121==
==5121== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 8)
==5121== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 8)
On further analysis and to arrest the 128 byte leak, i just commented the segment of code that was suspected as cause of this issue.
//char *the_link;
//the_link = malloc(sizeof(char) * (link_len +1)); // <=== here is where valgrind complains
//strncpy(the_link, &line[j + 1], link_len - 1);
//the_link[link_len] = '\0';
But still, after running valgrind it reported the same issue.So after close examination, there is one more malloc done in code which could be culprit. Hence after adding free(line) at the end of function call resolved this valgrind error.
char *line;
int line_len = 128;
line = malloc(sizeof(char)*line_len);
free(line); //added at the end of code
Now valgrind output is:
==5143== LEAK SUMMARY:
==5143== definitely lost: 0 bytes in 0 blocks
==5143== indirectly lost: 0 bytes in 0 blocks
==5143== possibly lost: 0 bytes in 0 blocks
==5143== still reachable: 172 bytes in 1 blocks
==5143== suppressed: 0 bytes in 0 blocks
==5143== Reachable blocks (those to which a pointer was found) are not shown.
==5143== To see them, rerun with: --leak-check=full --show-reachable=yes
==5143==
==5143== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 8)
==5143== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 8)
Please try out this change and let me know the results.
Upvotes: 1
Reputation: 9642
This code:
the_link = malloc(sizeof(char) * (link_len +1)); // <=== here is where valgrind complains
strncpy(the_link, &line[j + 1], link_len - 1);
the_link[link_len] = '\0';
You create a buffer of size link_len + 1
, then copy link_len - 1
characters into it (which writes to the_link[0]
to the_link[line_len-2]
, then write a NULL
terminator to the last byte in the array. This does not ever write to the_link[link_len-1]
. Either fix the strncpy
call or write some other known data in that location.
Upvotes: 3