mallocing char *和char **时的混乱大小

时间:2014-10-21 12:16:06

标签: c string

我有以下简单的代码来测试strncpy-ing overflow:

int main() {

  char *test = "hellooo";

  char **str_arr;
  str_arr = malloc(sizeof(char*));
  // allocate 5 bytes
  str_arr[0] = malloc(5);

  printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0]) ), sizeof(str_arr[0]));

  free(str_arr[0]);
  free(str_arr);
}

打印

hellooo size is 8

我的问题是为什么打印“hellooo”而不是“hell”,因为我只分配了5个字节?如何分配打印“地狱”(使用空终止)?

4 个答案:

答案 0 :(得分:1)

sizeof(str_arr[0])sizeof( char* ),即指针的大小

此外,你需要6个字节用于"你好",1个额外用于空终止

答案 1 :(得分:1)

您正在查看缓冲区溢出。你分配了5个字节,但你推的次数超过5个 char *不是真正的字符串类型,它只是char地址,因此您可以尝试从那里访问超过5个字节,这正是您所做的: 你写了8个字节"hellooo",它是一个8字节的数组(NUL终止的数组)。这种溢出通常会产生两种结果之一:

  1. 这样做会使您的应用程序访问一些您无法写入的内存,并且应用程序崩溃;
  2. 您的系统允许您写入您不想写入的内存(这实际上就是您的情况)。这种情况比前一种情况要糟糕,因为存在问题,但您无法轻易检测到,这可能会破坏程序中的其他数据。

答案 2 :(得分:0)

sizeof(str_arr[0])返回指针的大小,而不是您分配的字节数。 sizeof是一个编译时构造,它不知道你在运行时分配了多少字节。

strncpy中还存在一个很大的缺陷 - 如果字符串到达​​缓冲区的末尾,则不会得到空终止字符。你需要在复制后自己添加它。

strncpy(str_arr[0], test, 5);
str_arr[0][5] = 0;

答案 3 :(得分:0)

我希望这是正确的,但是因为:

char *test = "hellooo";
char **str_arr;
str_arr = malloc(sizeof(char*));
// allocate 5 bytes
str_arr[0] = malloc(5);

printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0])), sizeof(str_arr[0]));

就像是

test --> |h|e|l|l|o|o|o|\0|
          ^
          |
str_arr---

printf("%s size is %lu\n", strncpy ( str_arr[0], test, sizeof(str_arr[0])), sizeof(str_arr[0]));

将打印到\0,这意味着它将打印整个字符串。