I got the following code:
/* main.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (){
int i;
char *msg = "This is a simple and small message";
int len = strlen (msg);
char *new_msg = (char *) malloc (len);
for (i = 0; i < len; i++)
new_msg[i] = 'A';
printf ("%s\n", new_msg);
free (new_msg);
return 0;
}
I compiled it and then run it using valgrind with this command:
valgrind --leak-check=full --show-reachable=yes ./main
I got the this output:
==8286== Memcheck, a memory error detector
==8286== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8286== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==8286== Command: ./main
==8286==
==8286== Invalid read of size 1
==8286== at 0x4C2C1B4: strlen (vg_replace_strmem.c:412)
==8286== by 0x4EA09FB: puts (ioputs.c:36)
==8286== by 0x400636: main (main.c:12)
==8286== Address 0x51de062 is 0 bytes after a block of size 34 alloc'd
==8286== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==8286== by 0x400601: main (main.c:9)
==8286==
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
==8286==
==8286== HEAP SUMMARY:
==8286== in use at exit: 0 bytes in 0 blocks
==8286== total heap usage: 1 allocs, 1 frees, 34 bytes allocated
==8286==
==8286== All heap blocks were freed -- no leaks are possible
==8286==
==8286== For counts of detected and suppressed errors, rerun with: -v
==8286== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
I see that all the allocated memory was released, but I still get an error that I don't understand.
Appreciate the help.
This is a pretty straightforward error: there is an invalid read of new_msg because the null terminator is not there.
You have allocated the number of chars equal to the length of the original string, so currently there's no space to fit '\0' without making undefined behavior. Change your code as follows to fix the problem:
char *new_msg = malloc (len+1);
for (i = 0; i < len; i++)
new_msg[i] = 'A';
new_msg[len] = '\0';
There are a number of things to be changes in your code.
1) len should be of size_t not int, as strlen() returns of type size_t
2) (char *) malloc (len); drop the cast. This isn't an error, although there are reasons one should not cast.
3) new_msg is not NULL terminated \0. This is the reason the error is occurring.
you use strlen() to get length, but not contain the '\0'.
so when you malloc a new array, you should use len + 1, and set new_msg[len] is '\0'.
Related
I using valgrind to find a leak of memory. I wrote a function "prefix_to_string" to concatenate any two strings, but when I use the command
valgrind --leak-check=full ./helloworld
it says that I have a lot of leaks of memory. I really don't know where and why. I asked a friend why it was happening and he says that it was for doing malloc 2 times, 1 out the function and 1 in the function, but I don't know how to take care of that leak, because I think that I need to do those memory requests.
Here is the output that Valgrind gives me:
==9078== Memcheck, a memory error detector
==9078== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9078== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9078== Command: ./holamundo
==9078==
==9078== error calling PR_SET_PTRACER, vgdb might block
150:62
bye
==9078==
==9078== HEAP SUMMARY:
==9078== in use at exit: 63 bytes in 4 blocks
==9078== total heap usage: 5 allocs, 1 frees, 575 bytes allocated
==9078==
==9078== 5 bytes in 1 blocks are definitely lost in loss record 1 of 4
==9078== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078== by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078== by 0x4008AC: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 7 bytes in 1 blocks are definitely lost in loss record 2 of 4
==9078== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078== by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078== by 0x4008C3: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 8 bytes in 1 blocks are definitely lost in loss record 3 of 4
==9078== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078== by 0x400740: prefix_to_string (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078== by 0x4008D8: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== 43 bytes in 1 blocks are definitely lost in loss record 4 of 4
==9078== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9078== by 0x400897: main (in /mnt/c/Users/MrRaul/desktop/Tareas_edd/test_en_C/test_informales/holamundo)
==9078==
==9078== LEAK SUMMARY:
==9078== definitely lost: 63 bytes in 4 blocks
==9078== indirectly lost: 0 bytes in 0 blocks
==9078== possibly lost: 0 bytes in 0 blocks
==9078== still reachable: 0 bytes in 0 blocks
==9078== suppressed: 0 bytes in 0 blocks
==9078==
==9078== For counts of detected and suppressed errors, rerun with: -v
==9078== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
and here is the main of my code, so this way you can reproduce the problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
char* prefix_to_string(char* first_string,char* second_string){
char* name = first_string;
char* extension = second_string;
char* name_with_extension;
name_with_extension = malloc(strlen(name)*(sizeof(char))+strlen(extension)*(sizeof(char))+1); /* make space for the new string (should check the return value ...) */
strcpy(name_with_extension, name); /* copy name into the new var */
strcat(name_with_extension, extension); /* add the extension */
return name_with_extension;
}
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main(int argc, char *argv[]) {
int idx = 150;
int id = 62;
char str_idx[20];
char str_id[20];
itoa_simple( str_idx ,idx);
itoa_simple( str_id,id);
char *text_to_write;
text_to_write = malloc(2+sizeof(str_id)+sizeof(str_idx)+1);
text_to_write = prefix_to_string(str_idx,":");
text_to_write = prefix_to_string(text_to_write,str_id);
text_to_write = prefix_to_string(text_to_write,"\n");
printf("%s",text_to_write);
printf("bye\n");
free(text_to_write);
return 1;
}
You don't call free() often enough — you can't expect to avoid memory leaks if you don't call free() to release each separate memory allocation. And your repeated assignments to text_to_write in main() mean that you discard the only pointers to some of the allocated memory, so you can't free what was allocated. C requires endless care with memory management.
You have:
char *text_to_write;
text_to_write = malloc(2+sizeof(str_id)+sizeof(str_idx)+1);
// This assignment throws away the memory from the previous malloc
text_to_write = prefix_to_string(str_idx,":");
// This assignment throws away the memory from the previous prefix_to_string
text_to_write = prefix_to_string(text_to_write,str_id);
// This assignment also throws away the memory from the previous prefix_to_string
text_to_write = prefix_to_string(text_to_write,"\n");
printf("%s",text_to_write);
printf("bye\n");
// Calling free here only releases the last allocation from prefix_to_string
free(text_to_write);
You need something more like:
char *part1 = prefix_to_string(str_idx, ":");
char *part2 = prefix_to_string(part1, str_id);
char *part3 = prefix_to_string(part2, "\n");
printf("%s", part3);
printf("bye\n");
free(part1);
free(part2);
free(part3);
This example can be compiled and works as expected.
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 char * getstr() {
6 return strdup("Hello");
7 }
8
9 void *memcpy2(void *dest, const void *src, size_t len)
10 {
11 char * d = dest;
12 const char * s = src;
13
14 for (size_t i = 0; i < len; i++) {
15 d[i] = s[i];
16 }
17 return dest;
18 }
19
20 int main()
21 {
22 char buf[256];
23 char *str = getstr();
24
25 memset(buf, 0, 256);
26 memcpy2(buf, str, 255);
27
28 printf("%s\n", buf);
29
30 free(str);
31 return 0;
32 }
I reimplemented memcpy to have complete control over the test, making it independent from underlaying libc. As you can see, valgrind complains with this warning:
$ valgrind ./a.out
==9479== Memcheck, a memory error detector
==9479== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9479== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9479== Command: ./a.out
==9479==
==9479== Invalid read of size 1
==9479== at 0x4006B6: memcpy2 (k.c:15)
==9479== by 0x400731: main (k.c:26)
==9479== Address 0x5203046 is 0 bytes after a block of size 6 alloc'd
==9479== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9479== by 0x4EC48D9: strdup (strdup.c:42)
==9479== by 0x400673: getstr (k.c:6)
==9479== by 0x4006F3: main (k.c:23)
==9479==
Hello
==9479==
==9479== HEAP SUMMARY:
==9479== in use at exit: 0 bytes in 0 blocks
==9479== total heap usage: 2 allocs, 2 frees, 1,030 bytes allocated
==9479==
==9479== All heap blocks were freed -- no leaks are possible
==9479==
==9479== For counts of detected and suppressed errors, rerun with: -v
I don't understand why this "invalid read of size 1" message appears. It has not sense for me at all. Can some of you explain what is wrong with this code? Thank you in advance!
[...]
for (size_t i = 0; i < len; i++) {
d[i] = s[i];
}
[...]
Here len is 255, but the string pointed by s is less than 255 length, so you're going out of the array. You could maybe use the '\0' placed by strdup() to avoid this bug.
In main the str variable points to a memory area of six bytes length (the string "Hello" is the five characters in the string plus terminator, strdup will allocate strlen("Hello") + 1 bytes). Going out of bounds leads to undefined behavior.
And you are going out of bounds since you want to read 255 bytes from this six-byte area.
I was writting some simple code in C to test some memory allocation and pointers:
#include <stdlib.h>
#include <stdio.h>
int *randomAlloc(int n) {
int *address = NULL, i = 0;
address = malloc (n * sizeof(int));
for (i = 0; i < n ; i++){
*(address + i) = i ;
}
return address;
}
int main(int argc, char* argv[] ) {
int *address;
int n;
printf("Type vector size: ");
scanf("%d", &n);
address = randomAlloc(n);
free(address);
}
Yet for some reason when I type 4 as input valgrind outputs:
==2375== Memcheck, a memory error detector
==2375== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2375== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==2375== Command: ./a.out
==2375==
Type vector size: 4
==2375==
==2375== HEAP SUMMARY:
==2375== in use at exit: 0 bytes in 0 blocks
==2375== total heap usage: 3 allocs, 3 frees, 2,064 bytes allocated
==2375==
==2375== All heap blocks were freed -- no leaks are possible
==2375==
==2375== For counts of detected and suppressed errors, rerun with: -v
==2375== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
There is only one alloc and one free at the code. As n = 4, I'd expect it to alloc 4*4(sizeof(int))=16 bytes. Where is this comming from?
Valgrind keeps track of all memory allocations which occur in your application, including ones made internally by the C library. It is not (and cannot) be limited to allocations you make explicitly, as the C library can return pointers to memory which it has allocated internally.
Many standard I/O implementations will allocate buffers for use by printf() and/or scanf(), which is probably what accounts for the numbers you're seeing.
you should only have 1 memory alloc for the 'address' pointer's memory space. the other 2 memory allocs are for the printf and scanf functions.
to proof this, comment out the printf and scanf statements and you should see 1 alloc and 1 free when you use valgrind to execute the program...
I guess this is a newbie C question but I just could not find the answer. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *copy(char *in) {
char *out = (char *) malloc(strlen(in)+1);
strcpy(out,in);
return out;
}
int main() {
char *orig = (char *) malloc(100);
strcpy(orig,"TEST");
printf("Original reads : %s\n",orig);
printf("Copy reads : %s\n",copy(orig));
}
It works fine, however valgrind --leak-check=yes complains:
==4701== Memcheck, a memory error detector
==4701== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4701== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==4701== Command: ./copy
==4701==
Original reads : TEST
Copy reads : TEST
==4701==
==4701== HEAP SUMMARY:
==4701== in use at exit: 105 bytes in 2 blocks
==4701== total heap usage: 2 allocs, 0 frees, 105 bytes allocated
==4701==
==4701== 5 bytes in 1 blocks are definitely lost in loss record 1 of 2
==4701== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==4701== by 0x400609: copy (in /root/alfred/copy)
==4701== by 0x40066C: main (in /root/alfred/copy)
==4701==
==4701== 100 bytes in 1 blocks are definitely lost in loss record 2 of 2
==4701== at 0x4C28C20: malloc (vg_replace_malloc.c:296)
==4701== by 0x400638: main (in /root/alfred/copy)
==4701==
==4701== LEAK SUMMARY:
==4701== definitely lost: 105 bytes in 2 blocks
==4701== indirectly lost: 0 bytes in 0 blocks
==4701== possibly lost: 0 bytes in 0 blocks
==4701== still reachable: 0 bytes in 0 blocks
==4701== suppressed: 0 bytes in 0 blocks
==4701==
==4701== For counts of detected and suppressed errors, rerun with: -v
==4701== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Could someone please tell me what am I doing wrong? Thanks in advance!
You are malloc()'ing twice but do not free() them. Hence, valgrind complains about leaks.
Free the memory blocks you allocate and it should be fine.
char *p = copy(orig);
printf("Copy reads : %s\n", p);
free(orig);
free(p);
You are allocating memory block in the copy function, but never free it. So your code produces a memory leak, which is reported by the Valgrind. Correct version of your code should be
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *copy(char *in) {
char *out = malloc(strlen(in)+1);
//You need to check malloc result here!
strcpy(out,in);
return out;
}
int main() {
char *orig = (char *) malloc(100);
strcpy(orig,"TEST");
printf("Original reads : %s\n",orig);
char* copy = copy(orig);
printf("Copy reads : %s\n",copy);
free(orig);
free(copy);
return 0;
}
Also do not cast malloc() results.
I am using a 2D array, and am required to allocate it as shown:
char ** buf; //global var
void allocate()
{
buf = (char **) malloc (10 * sizeof (char*));
char * data = (char *) calloc (1, 1000);
int i;
for(i=0; i<10; i++)
buf[i] = &(data[i*100]);
}
int main()
{
allocate();
//something goes here
free(buf[0]);
free(buf);
return 0;
}
Now to free the arrays, since I cannot access the variable 'data' in main(), I cannot do free(data), hence I do free(buf[0]), assuming that I am freeing the entire array of 1000 elements. Is this the right way to do this? Does free(buf[0]) free the entire 'data' array?
(It would have been convenient to malloc every element of buf as buf[i] = malloc (100), but I cant do that since I HAVE to calloc a big block first).
Thanks in advance.
This code is correct. The value of buf[0] is &(data[0]) which is data by definition. This will free all the allocated memory.
Note that if you really just want one buffer to free, you can set:
offset = 10*sizeof(char*);
buf = calloc(10*100+offset);
and in the loop do:
buf[i] = buf + offset + i*100;
It is slightly unusual, but it is correct. You made two allocations; you make two frees. And you release the pointers that were allocated. All should be clean.
Did you run valgrind on your program?
Valgrind agrees with you. It is correct because buf[0] holds the pointer to the HEAD of the calloc'd memory block.
valgrind ./temp
==15404== Memcheck, a memory error detector
==15404== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==15404== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==15404== Command: ./temp
==15404==
==15404==
==15404== HEAP SUMMARY:
==15404== in use at exit: 0 bytes in 0 blocks
==15404== total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==15404==
==15404== All heap blocks were freed -- no leaks are possible
==15404==
==15404== For counts of detected and suppressed errors, rerun with: -v
==15404== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 7)