我的情况很奇怪。我有一个全局的二维char数组(用于表示字符串数组)。这些字符串的长度不超过28,包括终止字符,所以我只想使用一个维度设置为28的二维数组。另一个维度是在编译时确定的,但我的程序计算了多少个插槽在分配数组之前需要它。
我正在尝试像这样(全局)声明数组:
char** dictionary;
然后在我的一个函数中,我需要分配它。一旦我尝试使用字典[0] [0]或其他东西访问它们,这两个就会给我带来错误的访问错误:
dictionary = malloc(sizeof(char)*(28)*numberWords); //numberWords ends up being around 60000
//separately:
char newDict[numberWords][28];
dictionary = newDict;
是的,我是C的新手。希望我的学校教我而不是Java。
答案 0 :(得分:1)
如果你想对字符串进行全局访问,并且你知道字符串的最大长度,但是你不知道在程序执行之前你想要多少个字符串,那么你可以声明一个指向char的全局指针阵列[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] ) ;
}
答案 1 :(得分:1)
char newDict[numberWords][28];
dictionary = newDict;
首先关闭这部分是错误的,newDict是一个数组,它分配在一段内存中,而字典是一个指针指针,它散布在Heap的不同部分,你得到了错误的访问,因为字典正在寻找一个指针一个指针,newdict不包含指针,读取数组和指针,它们是不同的,虽然它们似乎以类似的方式工作
我看到你想使用数组表示法,因此你指定了dictionaty = newdict(这是错误的)
easyiset方法是
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.
为什么这样做?
数组表示法就像这样一个[x] = *(a + x),换句话说转到数组a,添加x并取数字在该内存位置,方括号称为语法糖,只是为了制作我们的生活更轻松,真正发生的是*(a + x)。
对于2d数组a [x] [y] = *(*(a + x)+ y)这是说去指针a,将x添加到指针中取出该内存中的内容*(a + x)然后将y添加到该内存中并将其指向*(*(a + x)+ y)
请注意,当我说向指针添加x时,它取决于数组保持的内容,比如你有一个int数组,因为int是4个字节,并且假设x是1,
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.
在内存中真正发生的是添加4个字节以转到+ 1的地址,编译器会为我们处理这个问题,所以这会使事情变得更容易,在你的情况下它是一个char,所以说一个[1] = *(a + 1),
回到你的问题。
dictionary [0] [0]会给你第一个单词中的第一个字母,因为你的字符串是空终止的,所以用%s得到整个字符串就像printf一样。
答案 2 :(得分:0)
如果您声明
char newDict[numberWords][28];
然后newDict 不一个char **
,而是一个实际的二维字符数组,所以赋值不起作用。另一方面,我认为newDict
声明是正确的方法。如果你真的想要这个全局指针的东西,那么可能就像
typedef char String[28]; //a String is a single array of 28 chars
String* dictionary;
将与newDict
的声明兼容(因为数组到指针衰减仅适用于“外部”级别,而不是递归到所有级别)。