C 如何声明字符*[20][250]

C 如何声明字符*[20][250],c,C,我有一个char*[]],我需要清空它,并时不时地创建一个新的,但我不知道如何一次又一次地重新初始化它 我试过了 args = malloc(sizeof(char*[20][250])*20); 及 但我仍然无法重新初始化阵列。数组是否真的是20 X 250,元素可能是char* 您如何遍历类型为*[20][250]的字符数组 这是用于execv的,将像这样使用 for(int i =0 ;i< maxArgs;i++){ execv(args[i][0],args[i]);

我有一个char*[]],我需要清空它,并时不时地创建一个新的,但我不知道如何一次又一次地重新初始化它

我试过了

args = malloc(sizeof(char*[20][250])*20);

但我仍然无法重新初始化阵列。数组是否真的是20 X 250,元素可能是char*

您如何遍历类型为*[20][250]的字符数组

这是用于execv的,将像这样使用

for(int i =0 ;i< maxArgs;i++){
    execv(args[i][0],args[i]);
    ERROR("failed to start");
}
for(int i=0;i
如果
args
声明为:

char* args[20][250];
char*** args;
您可以使用以下方法为该阵列的每个项目分配内存:

for (int i = 0; i < 20; ++i )
{
   for ( int j = 0; j < 250; ++j )
   {
      args[i][j] = malloc(sizeof(*args[i][j])*(SIZE_OF_STRING+1));
   }
}
您还需要几个
malloc
调用

步骤1

arg
分配内存

args = malloc(sizeof(*args)*20);
步骤2

args[0]-args[19]
分配内存

for (int i = 0; i < 20; ++i )
{
   args[i] = malloc(sizeof(*args[i])*250);
}
for (int i = 0; i < 20; ++i )
{
   for ( int j = 0; j < 250; ++j )
   {
      args[i][j] = malloc(sizeof(*args[i][j])*(SIZE_OF_STRING+1));
   }
}
将它们组合起来

args = malloc(sizeof(*args)*20);
for (int i = 0; i < 20; ++i )
{
   args[i] = malloc(sizeof(*args[i])*250);
   for ( int j = 0; j < 250; ++j )
   {
      args[i][j] = malloc(sizeof(*args[i][j])*(SIZE_OF_STRING+1));
   }
}
args=malloc(sizeof(*args)*20);
对于(int i=0;i<20;++i)
{
args[i]=malloc(sizeof(*args[i])*250;
对于(int j=0;j<250;++j)
{
args[i][j]=malloc(sizeof(*args[i][j])*(字符串的大小[u+1));
}
}

要清楚一点,当你想要一个类型为
char*[20][250]
的2D数组时,你在C语言中需要的是一个由
char*[250]
组成的20元素数组,每个数组都是由
char*
C字符串组成的250元素数组(每个字符串都是
char
的数组)

由于动态分配的2D数组不是单个内存区域,而是指向其他数组的指针数组,因此您无法在一个步骤1中完成此操作。执行所需操作的分配如下所示:

char ***args;

args = malloc(sizeof(char**[20]));
for (int i = 0; i < 20; ++i) {
    args[i] = malloc(sizeof(char*[250]));

    // optional, depending on your usage:
    for (int j = 0; j < 20; ++j)
        args[i][j] = ""; // This makes every `char *` element point to the same location in memory— the location of the compiled-in `""` / `(char *){ '\0' }`.
}

1好的,所以从技术上讲,可以将其分配为一个大blob,然后将20个元素的数组连接起来,指向blob中所需的偏移量。这会卷积
free()
ing,但通常是不必要的-对于大多数用例,性能增益可以忽略不计(并且您仍然需要
malloc())
指向2D blob的一个单独的指针数组)。通常只有当数据是大量2D数据(如图像数据)时,才会看到2D blob分配,
数据[x][y]
访问语法被避开,取而代之的是
数据[y*width+x]
语法,因为它的效率不低于编译器的效率,并且每个数据块不需要超过一对
malloc
/
free
对。

后缀运算符的优先级总是高于前缀,所以当您说

char*[20][250]
您将得到一个由20个数组组成的数组,其中包含250个指向字符的指针。可以使用括号将
*
更紧密地绑定:

char (*)[20][250]
表示指向20个数组(250个字符)的数组的指针。所以如果你有

char (*args)[20][250];
你可以用

args = malloc(sizeof(char [20][250]));

可以为2d数组声明typedef,如下所示:

    typedef char *array2d_t[20][250];
    typedef char *array1d_t[250];
现在,您可以
malloc
足够的内存来容纳此2d阵列的单个实例:

    array2d_t *array3d = malloc(1 * sizeof(*array3d));
因为指针的行为类似于它们指向的对象的数组,所以实际上我们有一个3d数组,它的第一个维度具有算术1(注意malloc中的
1*
),所以第一个索引只能是0。我们可以这样索引它:

    array3d[0][0][0] = "Hello";
    array3d[0][1][0] = "World";
    array3d[0][19][249] = "End of the world!";
或者,如果您愿意,我们可以显式取消对指针的引用:

    (*array3d)[0][0] = "Hello";
    (*array3d)[1][0] = "World";
    (*array3d)[19][249] = "End of the world!";
或者,我们可以为1d数组声明typedef,如下所示:

    typedef char *array2d_t[20][250];
    typedef char *array1d_t[250];
现在可以
malloc
足够的内存来容纳此1d阵列的20个实例:

    array1d_t *array2d = malloc(20 * sizeof(*array2d));
现在,我们无法使用以下内容对阵列进行索引:

    array2d[0][0] = "Hello";
    array2d[1][0] = "World";
    array2d[19][249] = "End of the world!";

假设它包含一个常规的c字符串,那么,如果我声明
inta[20][250]
,你是说它不是一个连续的内存块吗?@pat刚刚添加了一个脚注。你是对的,不是。C没有真正的二维数组支持;它只有指向任何其他支持的指针数组。如上所述声明
a
,然后打印
sizeof(a)
。您会发现它是
20*250*sizeof(int)
。这里找不到指针。@帕特:哦,对不起,我误读了你的评论-我以为你是在问malloc'ing
int[20][250]
,而不是让编译器堆栈分配来安排它。是的,你说得对。我忘了堆栈分配数组是如何工作的。如果你能用malloc的这种布局来回答这个问题,那就去吧!!但是IIRC,在编译时完成的内存布局会产生一些在
malloc()
-time时没有的快捷方式。有趣的风格:
malloc(sizeof(char[20][250])
@chux如果您希望分配的内存是一个20×250的单个字符的2D数组的形式,您会使用这种形式,正如Chris所说,“表示一个指向20个250个字符数组的指针”。如果你想要一个20×250的2D C字符串数组,我认为一个
malloc()
都不行。@chux:我更喜欢
malloc(sizeof*args)
,但我不认为你说的是这个。然而,我能想到的可能适合该数据类型的onky文本应用程序将是一个终端模拟器/编辑器/屏幕之类的东西,即使在那里,unicode也改变了大多数旧的确定性。@slipd.Thompson:“C字符串”不是一种类型,而是一个(有点模糊的)概念——一个以null结尾的字符序列。A
char[20][250]
是一种类型,可以容纳20个“C字符串”,每个字符串最多249个字符。取决于OP想要什么,所有这些可能相关,也可能不相关…@chrisdsodd Correct,“C字符串”不是一种类型,但它是一个高度特定的概念,具有普遍认可的类型(
char*
)和内存布局(零终止数组)。类似地,“宽C字符串”总是
wchar\u t*
和零项;“Pascal字符串”总是
char*
,第一个字节包含长度(通常为零)。我敢说,你会发现过去30年中的任何书籍或平台文档都不同意这一普遍存在的协议(如果不是标准的话)。|是的,OP想要的是