Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Malloc在main之外的函数中的大型2D字符串数组_C_Arrays_Malloc - Fatal编程技术网

Malloc在main之外的函数中的大型2D字符串数组

Malloc在main之外的函数中的大型2D字符串数组,c,arrays,malloc,C,Arrays,Malloc,我有一个以null结尾的字符串的大字典,主要声明为char dictionary[MAX_WORDS][MAX_WORD_LENGTH],其中MAX_WORDS可以是200000,MAX WORD LENGTH可以是50。我想用另一个函数为它分配一些空间,如: char ** AllocateMemory (char dictionary[MAX_WORDS][MAX_WORD_LENGTH]) { char **p; { p = (char **)malloc(

我有一个以null结尾的字符串的大字典,主要声明为char dictionary[MAX_WORDS][MAX_WORD_LENGTH],其中MAX_WORDS可以是200000,MAX WORD LENGTH可以是50。我想用另一个函数为它分配一些空间,如:

char ** AllocateMemory (char dictionary[MAX_WORDS][MAX_WORD_LENGTH])
{
    char **p;
    {
        p = (char **)malloc(sizeof(dictionary));
    }
    return p;
}
这将被称为在主要像

int main (void)
{
char dictionary[MAX_WORDS][MAX_WORD_LENGTH];

dictionary = AllocateMemory(dictionary);
}

我能以正常方式访问此内存吗?类似于另一个函数,它循环遍历字典中的单词,如i=0;字典[i][0];i++,然后是每个单词中的字母。另外,我可能在这里遗漏了一些东西,但是如果我为它添加了malloc空间,我已经通过声明字典创建了大量的空间?请纠正我,我肯定我只是有点困惑在这里与马洛克

您有多个问题。首先,您主要是将字典声明为一个或多个数组,这意味着它已经被分配。编译器为数组分配内存,这意味着您的分配是错误的

另一个问题是数组可能太大,因为大多数系统上的大多数编译器都分配局部变量,包括堆栈上的数组,并且堆栈空间有限。数组数组声明将分配200000*50字节,这几乎是10 MB,远远超过Windows上的大多数默认进程堆栈大小(如果只有单个MB,则默认堆栈大小)

当您解决上述问题,并使dictionary成为指向char的指针,而AllocateMemory返回的是char,那么您还有一些其他问题。第一个原因是AllocateMemory分配了错误的大小,另一个原因是数组数组与指向指针的指针不同,请参见。此外,在C语言中,您或任何返回void*的函数

程序的正确版本如下所示:

char ** AllocateMemory (void)
{
    char **p = malloc(MAX_WORDS * sizeof(*p));
    for (size_t i = 0; i < MAX_WORDS; ++i)
        p[i] = malloc(MAX_WORD_LENGTH + 1);  // +1 for string terminator

    return p;
}

int main (void)
{
    char **dictionary = AllocateMemory();

    // Not you can use `dictionary` as an array of arrays of characters,
    // or an array of strings
}
AllocateMemory可以返回char*[MAX\u WORD\u LENGTH]类型的指针,如下所示,以便于理解

#include <stdlib.h>

typedef char word[MAX_WORD_LENGTH];
word * AllocateMemory()
{
    word *p;
    {
        p = (word *)malloc(MAX_WORDS*sizeof(word));
    }
    return p;
}

int main (void)
{
    word * dictionary;
    dictionary = AllocateMemory();
    /* Access using dictionary[x][y] */
    return 0;
}

发布的代码有几个问题

我没有试图一一列举,而是为你的问题提供了一个可能的解决办法

struct dictionary
{
    char words[MAX_WORDS][ MAX_WORD_LENGTH];
};

struct dictionary *AllocateMemory ()
{
    char *p = NULL;

    if( NULL == (p = malloc( sizeof( struct dictionary ) ) ) )
    { // then malloc failed
        perror( "malloc for dictionary failed ");
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    return p;
}  // end function: AllocateMemory


which will be called in main like

int main (void)
{
    struct dictionary * pDictionary = AllocateMemory();

    free( pDictionary);
    return 0;
}  // end function: main

啊,我明白了。这更有道理。那么访问char字典**与访问字典[][]是一样的吗?为像单个字符串这样的小东西分配空间值得吗?如果是这样的话,我需要另一个函数来实现,其中malloc行是char*p=mallocMAX_WORDS*sizeofp+1;?然后在main char*string=AllocateMemory中;为什么要使数据结构复杂化?现在需要将一堆指针传递给free,而发布的答案缺少对每次调用malloc返回值的检查,以确保操作成功。我给出了最好的答案,因为它基本上清楚地解释了错误所在以及如何修复。@user3629249这不是一个复杂的数据结构,在编写C代码时,这是很常见的。是的,它不做任何错误检查,因为这会使代码变得混乱,更难阅读。@JoachimPileborg你的意思是不应该在C中使用void*?你提到的链接中的答案明确提到你不投,而不是你不需要投,也就是说,答案给出了不投的原因,这并不意味着我们不应该投。在C++中强制强制显式空格式的创建,有助于避免隐式类型转换引起的错误。即使对于C编译器,您也可以启用这样的警告,例如gcc中的-Wc++-compat。没有必要在C中强制转换malloc,我也没有理由就此与您争论,但我发现您不同意这一点,这让我问您,是否有什么东西使您能够像应该的那样在C中强制转换malloc。请坚持使用C语言。这里是对的一个解释。我不是在谈论特定的语言,也不是在谈论malloc,而是在谈论一般的编码实践。因为在C中发现了这样的问题,所以C++变得更加类型安全,它允许从空洞*中隐式转换,这是一种不安全的操作。我们仍然需要C中的void*,因为它是表示泛型指针的唯一方法。因此,与其建议类型不安全操作,不如让编译器警告这种转换,并显式强制转换,我们确信它是类型安全的。我不是说其他语言,请坚持使用C语言。如果你问你的编译器,这意味着你使用了错误的编译器和语言。我重复一遍,请坚持C语言,我们不能在C和C++之间有语言。人们在C或C++中都可以编码。笼统地说不应该在C中强制转换总是意味着纯C,这不是一个好的编码建议。如果有一些事情你不理解/接受,请告诉我。我放弃了。祝您有个美好的一天。