【问题标题】:The running results of program which has the same code are different under different platforms相同代码的程序在不同平台下运行结果不同
【发布时间】:2014-03-16 23:42:16
【问题描述】:

我写这样的代码来帮助我理解realloc()函数的用法。可能后面的代码有问题。

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 
 6 void dynamic_memory_management_func()
 7 {
 8     printf("------------dynamic_memory_management_func------------\n");
 9 
10     char *str1 = (char *)malloc(16);
11     memset(str1, 0, 16);
12     strcpy(str1, "0123456789AB");
13     char *str2 = realloc(str1, 8);
14     
15     printf("str1 value: %p [%s]\n", str1, str1);
16     printf("str2 value: %p [%s]\n", str2, str2);
17     
18     free(str2);
19     str2 = NULL;
20     
21     char *str3 = (char *)malloc(16);
22     memset(str3, 0, 16);
23     strcpy(str3, "0123456789AB");
24     char *str4 = realloc(str3, 64); 
25     strcpy(str4 + 12, "CDEFGHIJKLMN");
26     
27     printf("str3 value: %p [%s]\n", str3, str3);
28     printf("str4 value: %p [%s]\n", str4, str4);
29     
30     free(str4);
31     str4 = NULL;
32 
33 }
34 
35 int main(int argc, char *argv[])
36 {
37     dynamic_memory_management_func();
38     return 0;
39 }

令我惊讶的是,程序的运行结果不一样!

在mac os x 10.9.2下,结果是:

------------dynamic_memory_management_func------------
str1 value: 0x7ff7f1c03940 [0123456789AB]
str2 value: 0x7ff7f1c03940 [0123456789AB]
str3 value: 0x7ff7f1c03940 [0123456789AB]
str4 value: 0x7ff7f1c03950 [0123456789ABCDEFGHIJKLMN]

ubuntu 12.04 LTS下,结果为:

------------dynamic_memory_management_func------------
str1 value: 0xf6e010 [0123456789AB]
str2 value: 0xf6e010 [0123456789AB]
str3 value: 0xf6e010 [0123456789ABCDEFGHIGKLMN]
str4 value: 0xf6e010 [0123456789ABCDEFGHIGKLMN]

如您所见,str4 的指针地址是不同的。是什么原因造成的?

【问题讨论】:

  • 如果让两个人选一件 T 恤,你会希望他们都选一件粉色的吗?
  • 这提醒了我,所以应该在问题中生成带有代码的自动行号。
  • realloc() 可以返回与调用时不同的地址,即使它正在收缩内存。要记住的重要一点是,如果它不返回NULL,则旧地址(如果更改)是无效的。
  • @pmg 嘿家伙,我已经去掉了收缩操作。
  • 没有 UB 的版本在 ideone 可以正常工作。

标签: c


【解决方案1】:

这是预期的结果。

内存malloc() 每次调用时的选择取决于很多事情。它可能在不同的时间在同一台计算机上选择不同的内存!更不用说在不同的计算机上。

重要的是内存的内容。正如预期的那样,在您的测试中,它们(大约)相同。

但是你有一些错误

第 15 行:str1 无效。先前对realloc() 的调用已被设为无效。

第 16 行:str2 的内容不是“字符串”。它没有适当的终止符。用printf()打印无效

第 27 行:str3 无效。先前对realloc() 的调用已被设为无效。

【讨论】:

  • 编译器没有抱怨。
  • 尽管如此,它们是未定义的行为。未定义的行为可能不会被编译器捕获,它可能在运行程序时不会被捕获。您应该不惜一切代价避免使用 UB。
  • @lojunren 还有,你不应该转换mallocrealloc 的结果。
  • 编辑后 @Line 16:你不能用printf()"%s"打印str2,因为str2不是一个字符串;它没有零终止符。一旦你这样做了,UB 就被调用了,任何事情都可能发生。
  • @ajay 我重写了我的代码并重新编辑了我的问题。但结果仍然不同。
猜你喜欢
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多