不使用strcpy交换2个char指针数组,必须使用赋值运算符?

时间:2017-11-01 09:35:41

标签: c arrays pointers

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;意味着交换。

3 个答案:

答案 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)

这是修改程序的目标。