C 2d阵列初始化失败(segfault)

C 2d阵列初始化失败(segfault),c,C,我试图将一个指向char指针数组的指针传递给一个函数,在这里我要初始化它 然而,我的实现产生了一个分段错误,我不知道为什么。有人能帮忙吗 这是我的密码: #include<stdio.h> #include<string.h> #include<stdlib.h> void ret_2darr(char *(*str)[5]) { int i,j; for(i=0;i<3;i++) { for(j=0;j<

我试图将一个指向char指针数组的指针传递给一个函数,在这里我要初始化它

然而,我的实现产生了一个分段错误,我不知道为什么。有人能帮忙吗

这是我的密码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

void ret_2darr(char *(*str)[5])
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<=5;j++)
        {
            str[i][j]=(char *)malloc(sizeof("sach"));
            strcpy(str[i][j],"sach");
        }
    }
}

main()
{
    char *(*a)[5]=NULL;
    ret_2darr(a);
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<=5;j++)
        {
            printf("%s",a[i][j]);
        }
    }
 }
#包括
#包括
#包括
void ret_2darr(char*(*str)[5])
{
int i,j;

对于第7行中的(i=0;i,它应该是char*(*a)[5];不需要用NULL定义变量a。

咨询调试器,它说:

$ gcc -g test.c -o test
$ gdb ./test 
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...done.
(gdb) run
Starting program: /home/xand/code/stackoverflow/c/test 

Program received signal SIGSEGV, Segmentation fault.
0x000000000040064a in ret_2darr (str=0x0) at test.c:26
26        str[i][j]=(char *)malloc(sizeof("sach"));
(gdb) print str
$1 = (char *(*)[5]) 0x0
我们看到它是一个字符**[5](这是问题的开始)

因为我们只需要存储五个字符串,所以这应该是一个char*[5]

纠正这一点并在问题上流动会给

其他修复程序

  • 更正了主原型,并在返回0时添加了流程
  • 正确地重新定义

  • 更正了边界错误请考虑以下琐碎代码:

    int a = 0;
    func(a);
    ...
    
    void func (int x)
    {
      x = 5;
    }
    
    此代码不会修改变量
    a
    ,因为函数只修改了变量的副本,而不是它的实际内容

    指针或数组指针没有什么不同,如果您将作为参数传递的指针分配给其他地方,则该分配仅在该函数内有效。因此,您必须向指针传递地址。这是主要错误:该函数只会创建内存泄漏,因为您只有一个指向alloca的临时指针ted内存,函数返回时会立即忘记

    因此,您必须按地址传递数组指针…这是真正棘手的部分。您可以选择将指针传递给数组指针,或返回数组指针。这两种方法都会产生一些非常糟糕的C代码:

    但不要这样写代码!这是一个无法阅读的混乱局面。
    typedef
    是这里唯一明智的解决方案。例如:

    typedef char* arr_t[5];  // the array type
    arr_t* ptr; // a pointer to that array type
    
    其他错误:

    • 实际上,您从未在任何地方分配指针数组,您只是开始分配数组项,而没有分配数组本身

    • 您似乎想要2D数组,但使用的是1D数组类型。数组指针应该是
      char*(*a)[3][5]

    • 您访问数组指针不正确。
      str[i][j]
      的意思是“在数组编号[i]中,给我子数组[j]”,这是您想要的“在我的二维字符数组*中,给我项[i][j]”。再次,请确定您应该具有多少维度

    • 循环6个索引,而不是5个,以此类推



    我强烈建议您完全忘记数组指针,至少就函数而言是这样。将实际2D数组的分配留给调用方。使用
    char*arr[3][5]
    改为函数参数。

    调试器会怎么说?如果您使用gcc-Wall选项编译QQ,它会给您:警告:“a”在此函数中未初始化使用[-Wuninitialized],其他所有错误如何:
    sizeof(“sach”)
    不足以strore该字符串,以此类推。@LPs:我用gcc-Wall执行上述代码,它不会对sizeof函数抛出任何错误。它给出正确的输出。如果我错了,请纠正我……它不会触发警告,因为它是字符串文本。获得字符串长度的正确方法是
    strlen
    函数。“我们看到它是一个字符***(这是问题的开始)。因为我们只需要存储一个字符串数组,这应该是一个字符**”。哈,什么?这是胡说八道。2D数组不是指向指针的指针,也不兼容。请更正,因为我不想否决一个好的答案。
    $ gcc -g test.c.fixed.c -o test
    $ valgrind ./test
    ==18525== Memcheck, a memory error detector
    ==18525== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
    ==18525== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
    ==18525== Command: ./test
    ==18525== 
    sach
    sach
    sach
    sach
    sach
    ==18525== 
    ==18525== HEAP SUMMARY:
    ==18525==     in use at exit: 0 bytes in 0 blocks
    ==18525==   total heap usage: 5 allocs, 5 frees, 25 bytes allocated
    ==18525== 
    ==18525== All heap blocks were freed -- no leaks are possible
    ==18525== 
    ==18525== For counts of detected and suppressed errors, rerun with: -v
    ==18525== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    
    int a = 0;
    func(a);
    ...
    
    void func (int x)
    {
      x = 5;
    }
    
     void ret_2darr(char *(**str)[5]) // pass array pointer by reference
    
     char* (*(*ret_2darr)(void))[5]; // return array pointer from function
    
    typedef char* arr_t[5];  // the array type
    arr_t* ptr; // a pointer to that array type