[英]Writing to char* array in C throws segfault
I'm an infosec student, who has just begun learning C. I've been given an assignment to write a simple translation program using this prototype: char* dictionary[number_of_words][2];
我是一名信息安全专业的学生,刚刚开始学习C。我被分配了一个使用此原型编写简单翻译程序的程序:
char* dictionary[number_of_words][2];
. 。
The output should look something like this: 输出应如下所示:
Enter # of words to add: 3
dictionary[0][0]= plane
dictionary[0][1]= Flugzeug
dictionary[1][0]= house
dictionary[1][1]= Haus
dictionary[2][0]= cat
dictionary[2][1]= Katze
Enter english word to translate: house
---> Haus
My current (work in progress) code looks like this: 我当前的代码(正在进行中)如下所示:
void clean_stdin(void);
int main(void)
{
unsigned int i = 0,j = 0,size;
printf("Enter # of words to add: ");
scanf("%u",&size);
clean_stdin(); //clears input buffer
char* dictionary[size][2];
while(i <= size)
{
printf("dictionary[%u][%u]= ",i,j);
fgets(dictionary[i][j],100,stdin);
if(j >= 1)
{
j = 0;
++i;
}
else
j = 1;
}
return 0;
}
The code throws no errors when compiled with gcc -Wall main.c
, but this is the behaviour I get: 使用
gcc -Wall main.c
编译时,代码不会引发任何错误,但这是我得到的行为:
Enter # of words to add: 3
dictionary[0][0]= plane
dictionary[0][1]= Flugzeug
dictionary[1][0]= house
dictionary[1][1]= Haus
fish: “./a.out” terminated by signal SIGSEGV (Adressbereichsfehler)
*****
Enter # of words to add: 4
dictionary[0][0]= plane
fish: “./a.out” terminated by signal SIGSEGV (Adressbereichsfehler)
There's a fundamental flaw somewhere in my thought process. 我的思考过程中存在一个基本缺陷。 Any help/heads up is very appreciated.
任何帮助/注意都非常感谢。 Cheers!
干杯!
Let's look at this part of your code: 让我们看一下代码的这一部分:
char* dictionary[size][2];
while(i <= size)
{
printf("dictionary[%u][%u]= ",i,j);
fgets(dictionary[i][j],100,stdin);
Each dictionary[i][j]
is a pointer to char
, but you haven't set them to point anywhere meaningful yet - each array element contains some random bit pattern that may or may not correspond to a writable address. 每个
dictionary[i][j]
都是指向char
的指针,但是您尚未将它们设置为指向有意义的任何地方-每个数组元素都包含一些随机位模式,该模式可能对应也可能不对应可写地址。 Your first few entries get written somewhere , but eventually you try to write to a memory location you don't own or don't have access to. 您的前几个条目会写到某个地方 ,但最终您尝试写到一个您不拥有或无法访问的存储位置。
You will need to set aside additional memory to store each individual string. 您将需要预留额外的内存来存储每个单独的字符串。 You either need create a 3D array of
char
(not char *
): 您要么需要创建一个
char
的3D数组(不是char *
):
#define MAX_STR_LEN 100
...
char dictionary[size][2][MAX_STR_LEN+1];
or you will need to dynamically allocate memory for each array entry: 否则您将需要为每个数组条目动态分配内存:
while ( i < size ) // <, not <=
{
dictionary[i][j] = malloc( sizeof *dictionary[i][j] * (MAX_STR_LEN + 1));
if ( !dictionary[i][j] )
{
// memory allocation failed, handle error
}
printf("dictionary[%u][%u]= ",i,j);
fgets(dictionary[i][j],MAX_STR_LEN,stdin);
If you allocate memory dynamically, you will need to explicitly free
it when you're done: 如果动态分配内存,则需要在完成后显式
free
内存:
for ( i = 0; i < size; i++ )
{
free( dictionary[i][0] );
free( dictionary[i][1] );
}
instead of messing around with arrays of multiple dimensions, I suggest you use structures: 建议您不要使用多个维度的数组,而建议使用结构:
#include <stdio.h>
#include <string.h>
int main()
{
unsigned int size;
printf("Enter # of words to add: ");
if (scanf("%u", &size) != 1)
return 1; // cannot convert input to integer
#define WORD_MAX_SIZE 100
struct {
char word[WORD_MAX_SIZE];
char translation[WORD_MAX_SIZE];
} dictionary[size];
memset(dictionary, 0, sizeof(dictionary));
for (int i = 0; i < size; i++) {
printf("dictionary[%u].word= ", i);
fgets(dictionary[i].word, WORD_MAX_SIZE, stdin);
printf("dictionary[%u].translation= ", i);
fgets(dictionary[i].translation, WORD_MAX_SIZE, stdin);
}
// do something with your stuff
}
fgets(dictionary[i][j],100,stdin);
reads from an uninitialized variable ( dictionary[i][j]
was never given a value), which has undefined behavior. 从未初始化的变量(
dictionary[i][j]
从未提供值)中读取,该变量具有未定义的行为。
Also, i
is going out of bounds later. 另外,
i
以后会越界。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.