консультации с отладчиком, он говорит:
$ 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
при попытке доступа ул он пустой. нуль Разыменование вызывает Segfault ..
оглядываясь на то, как ул определяется и используется:
char *(*a)[5]=NULL;
мы видим, что это символ ** [5] (это начало проблемы).
Поскольку нам нужно всего лишь сохранить пять строк, это должно быть как символ * [5].
исправляя это и поток по вопросам дает
другие исправления
- corrected main prototype and added flow on return 0..
- redefined a properly
- corrected bounds error <=5 goes to < 5 (two times)
- removed malloc cast as redundant
- added \n for proper printing..
- added free(a[j]) to cleanup memory
- handle allocation errors from 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)
ссылка
Что говорит отладчик? – amdixon