1

在尝试解决问题时,我不小心将以下内容放入了我的代码中。

/* simplified for context*/
char *command = NULL;
char *new_command = (char *) malloc(10);
 ...
free(command);
command = (char *) malloc (new_command + 1);
strcpy(command, new_command);

它不仅遵守了运行没有问题,甚至消除了原来的问题。我已经将代码修复为:

command = (char *) malloc (strlen(new_command) + 1); 

这也有效,但我真的很想在修复它之前了解它为什么有效以及它到底在做什么。

编辑:实际上在代码中省略了 ... 命令已分配并存储了数据。command 和 new_command 在调用 free 之前都分配了内存并存储了数据。在其他函数中分配的,一个最初来自读入的文件,另一个是通过 TCP 套接字连接接收的。该程序将来自客户端的命令与当前确切的可执行文件(包括文件中的路径)进行匹配,然后调用该命令。一开始就忽略了所有这些,因为我认为它与发生的事情没有任何关系,以及为什么它在对 malloc 的错误调用(传递指针而不是大小)时完全起作用。

4

4 回答 4

6

它应该编译有很多警告。

malloc()如果运行,它应该使用第二个(基于地址到 a 的转换)分配一个不确定但可能非常大量的内存,size_t然后通过使用strcpy()从未正确初始化的内存调用可怕的未定义行为。

基本上,如果程序运行,应该会严重崩溃。但它可能不会——这就是未定义行为的美妙之处。一切皆有可能,这没关系,因为您调用了未定义的行为。

于 2013-08-30T20:19:14.973 回答
3

我假设你在谈论command = (char *) malloc (new_command + 1);

在这个调用中,指针的整数值new_command加 1,并且(可能相当大的)内存被分配。

假设new_command是一个指向0x00103456. 你基本上是在说:

command = (char *) malloc( 0x00103456 + 1 );

或者

command = (char *) malloc( 1061974 + 1 );

或者

command = (char *) malloc( 1061975 );
于 2013-08-30T20:21:03.023 回答
3
 /* simplified for context*/
   char *command = NULL;

声明一个空指针

   char *new_command = (char *) malloc(10);

声明一个指向字节字符数组的10指针

    ...
   free(command);

释放一个空指针。应该什么都不做。

   command = (char *) malloc (new_command + 1);

声明一个指向字节字符数组的指针new_command + 1。的值new_command是一个地址。因此,无论是什么地址,plus1都是您要分配的字节数。因此,如果地址是0x550000,它将分配0x550001字节。

   strcpy(command, new_command);

将字节从new_commandto复制到遇到command空值(的字节0)。没有任何预定义的内容写入new_command缓冲区(10分配了字节)。0因此,如果代码在访问不属于它的内存之前命中一个字节,程序将运行良好并复制new_command缓冲区中的任何垃圾command直到该点。如果它0在进入不属于它的内存之前没有遇到 a,它将因分段错误或类似错误而死。

于 2013-08-30T20:21:39.253 回答
2

您只是在观察未定义行为的工件(对于最后一行)。任何事情都可能发生。

于 2013-08-30T20:17:17.610 回答