二维chars数组返回SEGFAULT

时间:2016-01-25 23:58:43

标签: c arrays memory char allocation

我是C的初学者,我正在尝试创建一个像这样保存的字符串数组:

[1] [firststring]

[2] [secondstring]

[2] [thirdstring]

我的实现如下:

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter][50],"hello");
counter++;
//then i want to print it:
printf("my string: %s", for_pole[0][50]); //prints out first string
printf("my string: %s", for_pole[1][50]); //...and second one

但返回分段错误。

我应该使用一些动态的内存分配吗? 正如我告诉我的新手,对不好的问题感到抱歉。

5 个答案:

答案 0 :(得分:1)

我看不到代码中的第二个字符串。我只看到一个字符串“你好”。

您可以通过以下方式编写

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;
strcpy(for_pole[counter],"world");

//then i want to print it:
printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //...and second one

至于这个表达

for_pole[counter][50]

然后1)索引50在数组之外,因为索引的有效范围是0 - 49和2)它具有类型char而不是数组或指向char的指针函数strcpy或格式说明符%s。功能printf

答案 1 :(得分:1)

写作时

strcpy(for_pole[counter][50],"hello");

你正在写字符串"你好"到一个char。而且,它位于数组的位置50,从0到49。

你应该把它改成

strcpy(for_pole[counter],"hello");

因为" for_pole [i]"是第i个字符串和" for_pole [i] [j]"是该字符串的第j个字符。

同样,printf应为

printf("my string: %s", for_pole[0]);

我会添加一个' \ n'让事情变得更有条理

最后,代码将是这样的

int counter = 0;
char for_pole[50][50];
strcpy(for_pole[counter],"hello");
counter++;

printf("my string: %s\n", for_pole[0]); //prints out first string
printf("my string: %s\n", for_pole[1]); //prints out second string

答案 2 :(得分:0)

初始化for_pole变量为零。

char for_pole[50][50] = {0,};

答案 3 :(得分:0)

Jon.e,SEGFAULT有一些原因。 即使没有任何错误,也有缺乏记忆。

有些人告诉你,要注意编译器的消息和警告,是的,但这只是故事的一部分。

与SEGFAULT相关的是以下最值得注意的SEGFAULTS,我可以根据自己的经验告诉你:

<强> 1。您正在尝试访问不存在的索引。

数组的大小与声明数组时指定的大小完全相同。 查看此代码:

/* "Array out of bounds" error 
       valid indices for array foo
       are 0, 1, ... 999 */
  int foo[1000];
  for (int i = 0; i <= 1000 ; i++) 
    foo[i] = i; 

这里我们对一个不存在的索引进行非法访问。

<强> 2。您正尝试访问不存在的值。

在这种情况下,存在但存在值......

/* Illegal memory access if value of n is 
       not in the range 0, 1, ... 999 */
  int n;
  int foo[1000];
  for (int i = 0; i < n ; i++) 
    foo[i] = i;

这也是最常见的陷阱之一。 这个陷阱是如此根本,即使是经验丰富的开发人员有时会犯这样的错误。问题在于变量n的未初始化的内存。 初始化是将变量的值作为第一个值的过程。如果你想,我们可以说它是失去变量的童贞的过程。 当变量初始化时以及何时 - 不是时,存在非常混乱的规则。复杂的记忆。只需要始终初始化变量。

第3。您正尝试通过指针访问内存。

那个指针并没有指向任何地方。你正试图从NOWHERE读一些东西?它没有意义,是吗?

/* Illegal memory access because no memory
       is allocated for foo2 */
  float  *foo, *foo2; 
  foo = (float*)malloc(1000);
  foo2[0] = 1.0;

如果您忘记初始化变量(2-nd)或指针(3-rd情况),会发生什么。答案很广泛:从无到有,都是灾难。

为什么这样?因为内存已被很多应用程序使用,并且它在计算机上运行的数十万个应用程序之间共享。因此,当您创建变量时,它会在内存中为这些变量创建段,但不会清除该内存(确切地说,在某些情况下,它已被清空,在其他情况下 - 不是)只是假设从未清除。所以在这种情况下,无论是由变量还是由指针引起的问题(实际上它也是一个变量,但那是另一个故事),我们说变量存储'垃圾'。

注意,找到那种SEGFAULTS并不是很明显,有时它几乎是不可能的,所以你必须为这种情况做好准备,并且应该使用调试器例如gdb来消除这个bug。

还要避免这样的虚假错误。与我的学生一起练习表明这是非常常见的错误。

int n = 100;
int foo[n];

改为使用

int foo[100]

const int n = 100;
int foo[n];

enum N { N = 100 };
int is[N];

其他参考: Can a const variable be used to declare the size of an array in C? https://kb.iu.edu/d/aqsj

答案 4 :(得分:0)

你误解了......

...字符串和数组索引如何协同工作。字符串是一个字符数组。例如,这是一个字符串:

char some_string[20] = "Hello";

这就是你打印它的方式:

printf("%s\n", some_string);

这就是你使用strcpy()的方式:

strcpy(some_string, "Goodbye");

这就是你访问字符串中i个字符的方式:

/* Not compilable by itself; just an example. */
some_string[i]

注意您使用[...]的唯一时间是如何声明它并访问字符数组中的特定字符。但是,这是一个字符串。

对于字符串数组,您将其声明为二维字符数组,就像您使用for_pole一样:

/* An array of 50 strings, all of which can store a maximum of 49
 * characters, plus a null termination character for each string.
 */
char for_pole[50][50];

strcpy()counter字符串一起使用:

strcpy(for_pole[counter], "hello");

并打印第一个(0 - )字符串:

printf("my string: %s", for_pole[0]);

并打印第一个字符串的i个字符:

printf("string[%d]: %c", i, for_pole[0][i]);

再次注意我每次都没有使用[50]。如果您有一个字符串,则使用其名称和每个字符使用string[i]访问它。如果您有一个字符串数组,则使用其名称和每个字符串使用array[i]表示法访问该数组。要访问数组中j个字符串的i个字符:

/* Not compilable by itself; just an example. */
array[i][j]

为什么你的版本是segfaults

您不需要像每个表达式那样使用[50]。注意最后一个表达式array[i][j]来访问单个字符。由于字符由整数值表示,因此编译器将在必要时将该整数转换为指针。

这意味着执行strcpy(for_pole[counter][50],"hello");之类的操作会尝试复制字符串&#34; hello&#34;到编译器认为字符for_pole[counter][50]成立的任何内存地址。例如,如果字符是字母A,由我的系统上的整数65表示,那么程序将尝试复制字符串的所有6个字节&#34; hello&#34;到内存地址65.我的程序没有权限写入该内存地址,因此它是段错误的。这就是您遇到的问题。