在尝试解决问题时,我不小心将以下内容放入我的代码中。
/* 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);
这也有效,但我真的很想理解为什么它在我修复它以及它究竟在做什么之前有效。
编辑: 实际上在使用...命令省略的代码中已经分配并且存储了数据。 在调用free之前,command和new_command都分配了内存并将数据存储在其中。在其他函数中分配了一个,一个最初来自一个已读入的文件,另一个是通过TCP套接字连接接收的。程序将来自客户端的命令与当前确切的可执行文件(包括文件中的路径)进行匹配,然后调用该命令。把所有这些都留下来开始,因为我认为它与发生的事情没有任何关系,以及为什么它对malloc的错误调用(传递指针而不是大小)完全有效。
答案 0 :(得分:6)
它应该编译很多警告。
如果运行,它应该使用第二个malloc()
(基于地址转换为size_t
)分配不确定但可能非常大量的内存,然后通过使用来调用可怕的未定义行为对于从未正确初始化的内存strcpy()
。
基本上,该程序如果运行,应该会崩溃。但它可能不会 - 这是未定义行为的美妙。一切皆有可能,因为你调用了未定义的行为,这是可以的。
答案 1 :(得分: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 );
答案 2 :(得分: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
的值是一个地址。因此无论地址加上1
,您分配的字节数是多少。因此,如果地址为0x550000
,它将分配0x550001
个字节。
strcpy(command, new_command);
将字节从new_command
复制到command
,直到遇到null(0
的字节)。没有预先定义写入new_command
缓冲区(其中分配了10
个字节)。因此,如果代码在访问不属于它的内存之前命中0
字节,则程序将正常运行并将new_command
缓冲区中的任何垃圾复制到{{1}到那时为止。如果它在进入不属于它的内存之前没有遇到command
,它将因分段错误或类似错误而死亡。
答案 3 :(得分:2)
您只是观察未定义行为的工件(对于最后一行)。任何事情都可能发生。