Hello我有一个任务来修复这个程序,它不会生成valgrind生成的错误日志。
这是最近的代码
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char *tukar(){
char *a, *b, *c;
a = (char *) malloc(sizeof(char) * 50);
b = (char *) malloc(sizeof(char) * 50);
c = (char *) malloc(sizeof(char) * 50);
strcpy(a,"string a");
strcpy(b,"string b");
printf("\nBefore :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
c = b;
b = a;
a = c;
printf("\nAfter :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
free(a);
free(b);
return c;
}
int main(){
char *y = tukar();
printf("%s\n",y);
free(y);
getchar();
return 0;
}
打印出当前错误
==5300== Memcheck, a memory error detector
==5300== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5300== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==5300== Command: ./aa
==5300== Parent PID: 5110
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C30D22: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EAA931: puts (ioputs.c:35)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c0 is 0 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C30D34: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EAA931: puts (ioputs.c:35)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c1 is 1 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4EB5145: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c7 is 7 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4EB515C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1309)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c6 is 6 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C35028: __GI_mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EB5079: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c7 is 7 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid read of size 1
==5300== at 0x4C35038: __GI_mempcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x4EB5079: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1327)
==5300== by 0x4EAA9F2: puts (ioputs.c:40)
==5300== by 0x1088CB: main (atan.c:33)
==5300== Address 0x52010c5 is 5 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== Invalid free() / delete / delete[] / realloc()
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1088D7: main (atan.c:34)
==5300== Address 0x52010c0 is 0 bytes inside a block of size 50 free'd
==5300== at 0x4C2ED5B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x108897: tukar (atan.c:26)
==5300== by 0x1088BB: main (atan.c:32)
==5300== Block was alloc'd at
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087BF: tukar (atan.c:8)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300==
==5300== HEAP SUMMARY:
==5300== in use at exit: 50 bytes in 1 blocks
==5300== total heap usage: 5 allocs, 5 frees, 2,198 bytes allocated
==5300==
==5300== 50 bytes in 1 blocks are definitely lost in loss record 1 of 1
==5300== at 0x4C2DB2F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5300== by 0x1087CD: tukar (atan.c:9)
==5300== by 0x1088BB: main (atan.c:32)
==5300==
==5300== LEAK SUMMARY:
==5300== definitely lost: 50 bytes in 1 blocks
==5300== indirectly lost: 0 bytes in 0 blocks
==5300== possibly lost: 0 bytes in 0 blocks
==5300== still reachable: 0 bytes in 0 blocks
==5300== suppressed: 0 bytes in 0 blocks
==5300==
==5300== For counts of detected and suppressed errors, rerun with: -v
==5300== ERROR SUMMARY: 27 errors from 8 contexts (suppressed: 0 from 0)
我怀疑这些作业
c = b;
b = a;
a = c;
产生问题。但是,我的老师说它无法更改或替换为strcpy()。我正在考虑更换指针的地址,但指针已被声明为malloc()。
有没有办法在不更换作业的情况下修改代码?
PS:&#39; tukar&#39;意味着交换。答案 0 :(得分:1)
删除它:
c = (char *) malloc(sizeof(char) * 50);
你不需要分配第三个缓冲区,你从不使用它,实际上在进行交换时会覆盖它。让c
成为临时char *
。
此外,分配可以简化为:
a = malloc(50);
b = malloc(50);
因为你不需要施放,sizeof (char)
总是1。
为了完整起见,你还应该在依赖它之前检查分配是否成功。
然后正如评论中指出的那样删除return
,因为这根本没有意义。
答案 1 :(得分:1)
您的老师可能会钓到的是,您指出的那些作业只会改变指针所指向的位置,而不会制作数据的硬拷贝。有两个明显的错误:
c = b;
时,由于c
指向的内存丢失,您会收到内存泄漏。 b
指向的内容时,您还可以释放c
现在指向的内容。一种解决方案是永远不为c
分配任何内存,指定c
指向与b
相同的内存,然后不释放b
点在
答案 2 :(得分:0)
刚回来问朋友。他说回报c没有问题。他说同样关于c不需要是malloc() - ed(感谢放松&#39;参考)...而且关于free(a)导致内存泄漏到c(感谢Lundin&#39 ;参考)。
免费(a)导致c消失,它对b的引用也受到影响。修订后的计划将是
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
char *tukar(){
char *a, *b, *c;
a = malloc(50);
b = malloc(50);
strcpy(a,"string a");
strcpy(b,"string b");
printf("\nBefore :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
c = b;
b = a;
a = c;
printf("\nAfter :\n");
printf("a = %s\n",a);
printf("b = %s\n",b);
free(b);
return c;
}
int main(){
char *y;
y=tukar();
printf("%s",y);
free(y);
getchar();
return 0;
}
而valgrind给出输出
==2527== Memcheck, a memory error detector
==2527== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==2527== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==2527== Command: ./aa
==2527== Parent PID: 2159
==2527==
==2527==
==2527== HEAP SUMMARY:
==2527== in use at exit: 0 bytes in 0 blocks
==2527== total heap usage: 4 allocs, 4 frees, 2,148 bytes allocated
==2527==
==2527== All heap blocks were freed -- no leaks are possible
==2527==
==2527== For counts of detected and suppressed errors, rerun with: -v
==2527== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
这是修改程序的目标。