[英]Store multidimensional array in struct
I have a two dimensional array where the first dimension has a variable length but the second dimension is fixed. 我有一个二维数组,其中第一维的长度可变,但是第二维是固定的。 Now in a function call I could do something like
char foo[][3]
but what is the corresponding definition in a struct
? 现在,在函数调用中,我可以执行类似
char foo[][3]
但是struct
的相应定义是什么?
So in the example code I expected it to print each string in a line, but as expected it treats the stored pointer as a single dimensional array. 因此,在示例代码中,我希望它能将一行中的每个字符串都打印出来,但是正如预期的那样,它将存储的指针视为一维数组。
#include <stdlib.h>
#include <stdio.h>
struct payload_s {
size_t length;
char *text;
};
typedef struct payload_s payload;
static char some_text[4][3] = {"Ab", "Cd", "Ef", "Gh"};
payload* create_payload(char *text, size_t length)
{
payload *p = malloc(sizeof *p);
p->text = text;
p->length = length;
return p;
}
int main()
{
payload *p = create_payload(some_text, 4);
for (size_t i = 0; i < p->length; ++i)
printf("%zu: %s\n", i, &p->text[i]);
}
I mainly noticed this because of a warning: 我主要是因为警告而注意到这一点:
strut.c: In function ‘main’:
strut.c:23:33: warning: passing argument 1 of ‘create_payload’ from incompatible pointer type [-Wincompatible-pointer-types]
payload *p = create_payload(some_text, 4);
^~~~~~~~~
strut.c:13:10: note: expected ‘char *’ but argument is of type ‘char (*)[3]’
payload* create_payload(char *text, size_t length)
^~~~~~~~~~~~~~
I can get rid of this warning when the function is actually defined as payload* create_payload(char text[][3], size_t length)
, but then there is a warning a few lines later and the behavior didn't change: 当函数实际上定义为
payload* create_payload(char text[][3], size_t length)
,我可以摆脱此警告,但是稍后有一条警告,并且行为没有改变:
strut.c: In function ‘create_payload’:
strut.c:16:13: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
p->text = text;
^
Is the only solution to manually increment the pointer by the length of each value? 手动将指针增加每个值的长度是唯一的解决方案吗?
Use: 采用:
char (*text)[3];
instead of: 代替:
char *
since what you want here is a pointer to your 2D array, not a pointer to single char
. 因为您想要的是指向2D数组的指针,而不是单个
char
的指针。 Read more in C pointer to two dimensional array . 在C指向二维数组的指针中阅读更多内容。
Of course, it is suggested to use a define, or something similar for your dimension, instead of the hardcoded 3, like in my example. 当然,建议像我的示例一样,使用定义或类似的尺寸来代替维3。
Min. 闵。 Example:
例:
#include <stdlib.h>
#include <stdio.h>
#define M 3
struct payload_s {
size_t length;
char (*text)[M]; // change the member!
};
typedef struct payload_s payload;
// not need for null terminators in the strings,
// it will be placed automatically
static char some_text[4][M] = {"Ab", "Cd", "Ef", "Gh"};
// change the prototype as well
payload* create_payload(char (*text)[M], size_t length)
{
payload *p = malloc(sizeof *p);
p->text = text;
p->length = length;
return p;
}
int main()
{
payload *p = create_payload(some_text, 4);
for (size_t i = 0; i < p->length; ++i)
// no need to print the address now
// also 'zu' should be used for 'size_t'
printf("%zu: %s\n", i, p->text[i]);
}
Output: 输出:
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
0: Ab
1: Cd
2: Ef
3: Gh
PS - Check what malloc()
returns, to see if the memory was actually allocated (of course on real code, not in min. egs). PS-检查
malloc()
返回什么,以查看是否实际分配了内存(当然是在实际代码上,而不是在最小例中)。
this line: 这行:
static char some_text[4][3] = {"Ab\0", "Cd\0", "Ef\0", "Gh\0"};
is trying to initialize an array of 3 bytes in each entry with values that are 4 bytes in each entry. 正在尝试初始化每个条目中3个字节的数组,并在每个条目中使用4个字节的值。
note: "AB\\0" is 4 bytes because declaring a char array Always appends a NUL byte to the end of the array. 注意:“ AB \\ 0”为4个字节,因为声明一个char数组始终将NUL字节附加到该数组的末尾。
Suggest: 建议:
static char some_text[4][3] = {"Ab", "Cd", "Ef", "Gh"};
The call to printf()
contains several errors, which your compiler should have told you about. 对
printf()
的调用包含一些错误,您的编译器应已将这些错误告知您。
The field: char *text;
字段:
char *text;
is actually pointing to a 2D array, so should be declared accordingly. 实际上指向2D数组,因此应相应声明。
Need to perform error checking on the call to malloc()
. 需要对
malloc()
的调用执行错误检查。
here is a version of the code, will all (reasonable) corrections applied. 这是代码的一个版本,将应用所有(合理的)更正。
#include <stdlib.h>
#include <stdio.h>
struct payload_s
{
size_t length;
char **text;
};
static char *some_text[] = {"Ab", "Cd", "Ef", "Gh"};
struct payload_s* create_payload(char **text, size_t length)
{
payload *p = malloc(sizeof (struct payload_s));
if( !p )
{
perror( "malloc for instance of payload failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
p->text = text;
p->length = length;
return p;
}
int main( void )
{
//payload *p = create_payload(some_text, 4);
payload *p = create_payload(some_text, sizeof(some_text) / sizeof( *some_text ) );
for (size_t i = 0; i < p->length; ++i)
printf("%lu: %s\n", i, p->text[i]);
}
The result of the above code is: 上面的代码的结果是:
0: Ab
1: Cd
2: Ef
3: Gh
You are using incompatible pointers that can not be converted implicitly to each other. 您正在使用不能相互隐式转换的不兼容指针。
Character array some_text
declared like 字符数组
some_text
声明为
static char some_text[4][3] = {"Ab\0", "Cd\0", "Ef\0", "Gh\0"};
when it is used in expression as for example used as an argument it is implicitly converted to pointer to its first element and has type char ( * )[3]
. 当在表达式中使用它(例如用作参数)时,它隐式转换为指向其第一个元素的指针,并且类型为
char ( * )[3]
。 It si not the same as pointer of type char *
. 它与
char *
类型的指针不同。
It looks like you need a structure with a flexible array. 看起来您需要具有灵活数组的结构。
Here is a demonstrative program that shows how such a structure can be used. 这是一个演示程序,显示了如何使用这种结构。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
struct payload_s
{
size_t length;
char text[][N];
};
struct payload_s * create_payload( char( *text )[N], size_t length )
{
struct payload_s *p = malloc( sizeof( struct payload_s ) +
length * sizeof( char[N] ) );
p->length = length;
for ( size_t i = 0; i < length; i++ ) strcpy( p->text[i], text[i] );
return p;
}
void free_payload( struct payload_s *p )
{
free( p );
}
int main(void)
{
char some_text[4][N] = {"Ab", "Cd", "Ef", "Gh"};
char another_text[5][N] = {"Bb", "Dd", "Ff", "Hh", "Jj"};
struct payload_s *p1 = create_payload( some_text,
sizeof( some_text ) / sizeof( *some_text ) );
struct payload_s *p2 = create_payload( another_text,
sizeof( another_text ) / sizeof( *another_text ) );
for ( size_t i = 0; i < p1->length; i++ )
{
printf( "%s ", p1->text[i] );
}
printf( "\n" );
for ( size_t i = 0; i < p2->length; i++ )
{
printf( "%s ", p2->text[i] );
}
printf( "\n" );
free_payload( p2 );
free_payload( p1 );
return 0;
}
Its output is 它的输出是
Ab Cd Ef Gh
Bb Dd Ff Hh Jj
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.