当我在编译时只知道一个维度时,在C中使用2D数组全局变量

当我在编译时只知道一个维度时,在C中使用2D数组全局变量,c,arrays,variables,2d,global,C,Arrays,Variables,2d,Global,我的处境很奇怪。我有一个全局2D字符数组(表示字符串数组)。这些字符串的长度不超过28,包括终止字符,所以我只想使用一维设置为28的2D数组。另一个维度是在编译时确定的,但我的程序会计算在分配数组之前需要多少插槽 我试图像这样声明数组(全局): 然后在我的一个函数中,我需要分配它。当我尝试使用字典[0][0]或其他方法访问它们时,这两个会给我带来严重的访问错误: dictionary = malloc(sizeof(char)*(28)*numberWords); //numberWords e

我的处境很奇怪。我有一个全局2D字符数组(表示字符串数组)。这些字符串的长度不超过28,包括终止字符,所以我只想使用一维设置为28的2D数组。另一个维度是在编译时确定的,但我的程序会计算在分配数组之前需要多少插槽

我试图像这样声明数组(全局):

然后在我的一个函数中,我需要分配它。当我尝试使用字典[0][0]或其他方法访问它们时,这两个会给我带来严重的访问错误:

dictionary = malloc(sizeof(char)*(28)*numberWords); //numberWords ends up being around 60000
//separately:
char newDict[numberWords][28];
dictionary = newDict;
是的,我对C有点陌生。希望我的学校教我它而不是Java。

如果你声明

char newDict[numberWords][28];
那么newDict不是一个
字符**
,而是一个实际的二维字符数组,因此赋值不起作用。另一方面,我认为
newDict
声明是正确的选择。如果你真的想要这个全局指针,那么

typedef char String[28]; //a String is a single array of 28 chars
String* dictionary;

将与您的
newDict
声明兼容(因为数组到指针的衰减只在“外部”级别上工作,而不是递归到所有级别)。

如果您想全局访问字符串,并且知道字符串的最大长度,但在程序执行之前不知道要有多少字符串,然后可以声明一个指向字符数组的全局指针[28]。这里的好处还在于内存是连续的

#define MAX 28

char ( *p_array)[MAX] ;

void func( int size )
{
    p_array = malloc( sizeof( *p_array ) * size ) ;

    for( int i = 0 ; i < size ; i++ )
        snprintf( p_array[i] , sizeof( *p_array ) , "test string no.: %d" , i ) ;

    for( int i = 0 ; i < size ; i++ )
        printf("%s\n" , p_array[i] ) ;
}
#定义最大值28
字符(*p_数组)[MAX];
void func(整数大小)
{
p_数组=malloc(sizeof(*p_数组)*大小);
对于(int i=0;i
首先,这部分是错误的,newDict是一个数组,它被分配在一段内存中,而dictionary是指向指针的指针,它分散在堆的不同部分,你得到了错误的访问,因为dictionary正在寻找指向指针的指针,而newDict不包含指针,读取数组和指针,虽然它们似乎以相似的方式工作,但它们是不同的

我发现您想要使用数组表示法,因此您分配了dictionary=newdict(这是错误的)

最简单的方法是

char ** dictionary;
 dictionary = (char **)malloc(sizeof(char *)*NUMBER_OF_WORDS)

 for(int i =0;i<NUM_WORDS,i++)
 {
 dictionary[i] = (char *)malloc(sizeof(char)*28);
 }

 now you can access each word like this 
 dictionary[word_number][the letter]; 

 //so in your code you said char ** dictionaty, lets go through this, dictionary is a 
   pointer to another pointer that points to a char. look at my code, dictionary is a 
   pointer, that points to another pointer that eventuall points to a char.
内存中真正发生的事情是将4个字节添加到a+1的地址,编译器为我们处理这个问题,因此这使事情变得更容易,在您的例子中,它是一个字符,所以假设a[1]=*(a+1)

回到你的问题上来


字典[0][0]将为您提供第一个单词中的第一个字母,因为您的字符串以null结尾,所以您可以使用类似printf的%s来获取整个字符串。

谢谢。所有这些答案都是可能的解决方案,但这正是我想要的。但也许为了提高效率,我应该换一种方式。
char newDict[numberWords][28];
dictionary = newDict;
char ** dictionary;
 dictionary = (char **)malloc(sizeof(char *)*NUMBER_OF_WORDS)

 for(int i =0;i<NUM_WORDS,i++)
 {
 dictionary[i] = (char *)malloc(sizeof(char)*28);
 }

 now you can access each word like this 
 dictionary[word_number][the letter]; 

 //so in your code you said char ** dictionaty, lets go through this, dictionary is a 
   pointer to another pointer that points to a char. look at my code, dictionary is a 
   pointer, that points to another pointer that eventuall points to a char.
int a[10]
a[1] = *(a+1) (the compiler actually adds 4 bytes to the address although we 
said 1  obviously since an int is 4 bytes, this 
is pointer arithmetic you should read up on it. this makes things much easier.