2d阵列的初始化失败(段错误)

时间:2015-09-28 09:24:51

标签: c

我正在尝试将指针传递给函数的char指针数组,我想在其中初始化它。

然而,我的实现产生了一个分段错误,我无法弄清楚原因。有人可以帮忙吗?

这是我的代码:

static_cast<something>

3 个答案:

答案 0 :(得分:2)

考虑这个简单的代码:

int a = 0;
func(a);
...

void func (int x)
{
  x = 5;
}

此代码不会修改变量a,因为该函数只修改了变量的副本,而不是它的实际内容。

指针或数组指针没有什么不同,如果您将作为参数传递的指针指定为指向其他位置的指针,则该指派仅在该函数中有效。所以你必须将一个地址传递给指针。这是一个主要的错误:该函数只会产生一个内存泄漏,因为你只有一个临时指针指向分配的内存,一旦函数返回就会忘记它。

所以你必须按地址传递数组指针......这是一个非常棘手的部分。您的选项是传递指向数组指针的指针,或返回数组指针。要么会产生一些严重的邪恶的 C代码:

 void ret_2darr(char *(**str)[5]) // pass array pointer by reference

 char* (*(*ret_2darr)(void))[5]; // return array pointer from function
但是,不要写这样的代码!这是一个难以理解的混乱。 typedef是唯一理智的解决方案。例如:

typedef char* arr_t[5];  // the array type
arr_t* ptr; // a pointer to that array type

其他错误:

  • 您实际上从不在任何地方分配指针数组,您只需开始分配数组的项目而不分配现有的数组本身。

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

  • 您错误地访问了数组指针。 str[i][j]表示&#34;在数组编号[i]中,给我子数组[j]&#34;,你更喜欢&#34;在我的2D数组char *中,给我项[ i] [j]&#34 ;.再次,请考虑您应该拥有多少维度。

  • 你循环超过6个索引而不是5等。

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

答案 1 :(得分:1)

咨询调试器,它说:

$ 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

这意味着在ret_2darr中当您尝试访问str时,它为null。 null dereferencing正在导致段错误。

回顾如何定义和使用str:

char *(*a)[5]=NULL;

我们看到它是一个char ** [5](这是问题的开始)。

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

纠正这个并在问题上流动

其他修正

  
      
  • 更正了主要原型,并在返回0 ..
  • 时添加了流量   
  • 正确重新定义
  •   
  • 校正的边界误差&lt; = 5进入&lt; 5(两次)
  •   
  • 删除了malloc cast为冗余
  •   
  • 添加\ n以便正确打印..
  •   
  • 免费添加(a [j])以清理内存
  •   
  • 处理来自malloc的分配错误
  •   

调整后的代码

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

int ret_2darr(char *a[5]);

int main(void)
{
  char *a[5];
  if(ret_2darr(a))
  {
    // handle/log allocation errors here..
    return 0;
  }
  int i,j;
  for(j=0;j<5;j++)
  {
    printf("%s\n",a[j]);
    free(a[j]);
  }
  return 0;
}

int ret_2darr(char *str[5])
{
  int j;
  memset(str, 5*sizeof(char *), 0);
  for(j=0;j<5;j++)
  {
    str[j]=malloc(sizeof("sach"));
    if(!str[j])goto err0;
    strcpy(str[j],"sach");
  }
  return 0;

err0:
  for(;j>=0;j--)
  {
    if(str[j])free(str[j]);
  }
  return 1;
}

<强>输出

$ 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)

<强>参考

答案 2 :(得分:-1)

第7行应该是char *(* a)[5];无需使用NULL定义变量a。