动态内存分配的字符指针分析

时间:2015-06-25 20:01:10

标签: c string pointers dynamic-memory-allocation strcpy

我在C中编写了以下代码。我需要了解在字符指针通过malloc()动态分配内存后如何执行字符串复制操作。

我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFSZ 20
int main()
{
        char *name = NULL;
        char my_name[BUFFSZ] ;
        memset(my_name,0,BUFFSZ);
        strcpy(my_name,  "vinothkumarsaradavallivaradathirupathi");
        printf("string copied is %s\n",my_name);
        if ((name = malloc(1 + strlen(my_name)+1)) != NULL)
                strcpy(name,my_name);
        printf("Name is %s\n",name);
        free(name);
        name = NULL;
        return 0;
}

实际输出:

string copied is vinothkumarsaradavallivaradathirupathi
Name is vinothkumarsaradavalliva��

根据代码,我预计下面的输出但只有一个以上。如果有人清楚地解释这一点会很有帮助。

预期产量:

string copied is vinothkumarsaradaval
Name is vinothkumarsaradaval

当我在GDB中运行此代码时,我得到以下输出:

Breakpoint 2, main () at first_pgm.c:12
12              memset(my_name,0,BUFFSZ);
(gdb) n
14              strcpy(my_name,  "vinothkumarsaradavallivaradathirupathi");
(gdb) p name
$1 = 0x0
(gdb) p my_name
$2 = '\000' <repeats 19 times>
(gdb) n

Breakpoint 3, main () at first_pgm.c:15
15              printf("string copied is %s\n",my_name);
(gdb) p my_name
$3 = "vinothkumarsaradaval"
(gdb) n
string copied is vinothkumarsaradavallivaradathirupathi

在这里,为什么&#34; $ 3&#34;和#34;字符串复制&#34;输出有冲突吗?

3 个答案:

答案 0 :(得分:2)

  

预期输出

等待。您不能从此代码中获得预期的输出。此代码生成undefined behavior

在您的代码中

 strcpy(my_name,  "vinothkumarsaradavallivaradathirupathi")

你超出了分配的内存。在您的情况下,my_name没有足够的内存来保存源字符串文字的完整内容。

结果:未定义的行为。

请将足够的内存分配给目标缓冲区,以便它可以保存源字符串和空终止符。

那就是说,

  1. Do not cast malloc()和家人的返回值。

  2. 当您不打算使用任何命令行参数时,main()的推荐(相当,必需)签名为int main(void)

答案 1 :(得分:1)

您正在复制超过允许的19个字节,这会导致未定义的行为。因为你的数组只能存储20个字符,但你要复制39个字符。

只需更改

synchronized

它会起作用。

另外,这个

#define BUFSIZE 39

非常难看,

  1. 不要转换if (NULL != (name = (char *)malloc(sizeof(char)*(strlen(my_name)+1)))) 的返回值malloc()并将其转换为任何其他指针类型而不进行转换。
  2. 请勿使用void *,因为根据定义,它是1。
  3. 修复代码看起来像

    sizeof(char)

    您检查if ((name = malloc(1 + strlen(my_name))) != NULL) 但仍然执行此操作

    NULL

    这会在printf("Name is %s\n", name) 的情况下导致未定义的行为。

答案 2 :(得分:0)

这是经典的缓冲区溢出。 strcpy在找到终止'\0'字符之前不会停止将字符写入其目标缓冲区。它所写入的内存是实现定义的,这就是为什么你不能可靠地读出它的原因。使用strncpy对要复制的数据量strcpy设置上限。