分配顶级数组

时间:2017-06-26 09:50:06

标签: c arrays malloc

今天我遇到了动态创建char数组的问题。
以下代码是导致问题的示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void){

        char** top = NULL;
        top = malloc(30*sizeof(char));

        printf("sizeof top:%d\n",sizeof(top));

        for(int  i = 0; i < sizeof(top); i++){
                top[i] = malloc(12*sizeof(char));
                strcpy(top[i],"Lorem Ipsum");
        }


        for(int i = 0; i < sizeof(top); i++){
                printf("%d: %s\tsize: %d\n",i,top[i],strlen(top[i]));
        }
}

预期输出如下:

sizeof top:30
0: Lorem Ipsum  size: 11
1: Lorem Ipsum  size: 11
2: Lorem Ipsum  size: 11
3: Lorem Ipsum  size: 11
4: Lorem Ipsum  size: 11
5: Lorem Ipsum  size: 11
6: Lorem Ipsum  size: 11
7: Lorem Ipsum  size: 11

但我得到了这个输出:

sizeof top:8
0:      size: 0
1: Lorem Ipsum  size: 11
2: Lorem Ipsum  size: 11
3: Lorem Ipsum  size: 11
4: Lorem Ipsum  size: 11
5: Lorem Ipsum  size: 11
6: Lorem Ipsum  size: 11
7: Lorem Ipsum  size: 11

我已经尝试更改所有阵列的大小,但它保持不变。我真的不明白为什么顶部的大小保持在8,即使我尝试分配更多的内存,以及为什么存储到数组的第一个字符串将无法正确显示而其他字符串。经过一些研究,我找不到任何有关类似问题的信息。有人可以向我解释这种情况或推荐一个可靠的来源吗?

提前致谢!

编辑:我认为这个问题与char **数组的使用有关(它确实如此)。我不知道真正的问题是sizeof返回的值。 非常感谢您的回答和快速帮助。

2 个答案:

答案 0 :(得分:0)

这很可能不会导致你(可能)想要的结果:

char** top = malloc(30*sizeof(char));

top is本身是一个指向char *的指针,因此它可以指向char *本身或指向数组。所以你真的需要:

char** top = malloc(30*sizeof(char*));
//                                ^

但是top是指针,sizeof(top)会给你系统上指针(任意一个)的大小,很可能是8(就像现代的64位硬件一样)。

如果你直接将它应用于数组,那么

sizeof只能按预期工作(例如,不将它们传递给函数,在这种情况下它们只作为指针传递!):

int a[7];
size_t n0 = sizeof(a); // n == 7*sizeof(int)
// if you want the number of elements (which is what you normally do)
// (and you missed that above, too!):
size_t n1 = sizeof(a)/sizeof(*a);
// alternatively:
size_t n2 = sizeof(a)/sizeof(a[0]);

当你使用指针时,你必须将你的数组长度保持在别处:

for(int i = 0; i < 30; ++i)
//                 ^ instead of sizeof(top) - but bad, see below!

嗯,当然,现在你的代码中有魔术数字,这正是你(正确!)想要避免的......

解决方案:使用常量,可以是const变量,也可以是define:

size_t const NumberOfElements = 30;
#define NUMBER_OF_ELEMENTS 30

如果你想能够修改长度(例如通过realloc),那么定义就出来了,你需要一个非const变量:

size_t NumberOfElements = 30;

如果你不是一直使用整个阵列,你可能需要两个变量,我个人喜欢使用容量和大小(以C ++的风格std::vector) :

size_t capacity = 32; // initial capacity
size_t size     = 0;  // current size

如果需要,请考虑使用前缀来避免名称冲突。

答案 1 :(得分:0)

sizeof(top)编译时中进行评估。

malloc运行时中执行。

因此,无法在运行时从30接收sizeof(top)个字节。

  • VLA(可变长度数组)是一个例外。在这种情况下,sizeof将在运行时动态评估。

    int x;
    scanf("%d", &x);
    char ch[x];
    printf("%d\n", (int)sizeof ch);
    

    如果将7读入xsizeof的{​​{1}}将在运行时进行评估,并打印ch