memset导致程序崩溃?

3

我在使用 memset 的时候遇到了困难。

如果在我的数组中写入数据,我的程序就会崩溃。如果将 memset 注释掉,那么就没有问题。

我的结构体类型如下:

typedef struct  
{
    char Frage  [maxLEN_F_A];
    char Antwort[maxLEN_F_A];
} Fragenfeld;

我的结构体声明:

Fragenfeld QuizFragen[maxFragen];
Fragenfeld *ptrQuizFragen = QuizFragen;

memset 函数:

memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));

我编辑地址值的函数:

int Fragen_einlesen(Fragenfeld *Quizfragen)
{
....
strncpy(Quizfragen->Frage,sEingabe, maxLEN_F_A);
}

5
&ptrQuizFragen 应该改为 ptrQuizFragen。请花一分钟考虑这个。 - Mad Physicist
2个回答

5

当你编写代码时

memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));

你要表达的意思是“请设置大量字节,从指针变量ptrQuizFragen的地址开始清零。"注意,这与说“请设置大量字节,ptrQuizFragen所指向的数组的开头开始清零”不同。这意味着字节被写入了错误的位置,这导致了段错误。

图形上来看,该设置大概长这样:

ptrQuizFragen
+-----------+
|           |
+-----------+
      |
      v
+-----------+-----------+-----------+ ... +-----------+
|           |           |           |     |           |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen

你所写的这行代码将从内存中指向ptrQuizFragen位置的字节开始,具体做法如下:
ptrQuizFragen
+-----------+
| 00000000000000000000000000000000000 ... 000000000000 (oops!)
+-----------+
       
       
+-----------+-----------+-----------+ ... +-----------+
|           |           |           |     |           |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen

您想要的那一行是:
memset(ptrQuizFragen, 0, maxFragen * sizeof(Fragenfeld));

这句话的意思是将字节放置在由 ptrQuizFragen 指向的内存位置。这样做会实现以下操作:

ptrQuizFragen
+-----------+
|           |
+-----------+
      |
      v
+-----------+-----------+-----------+ ... +-----------+
| 000000000 | 000000000 | 000000000 |     | 000000000 |
+-----------+-----------+-----------+ ... +-----------+
QuizFragen

我喜欢你对正在发生的事情所做的图形说明。 - JeremyP
非常感谢您提供的这个有用的答案! - zombieanfuehrer

3

This ...

memset(&ptrQuizFragen,0,maxFragen*sizeof(Fragenfeld));

该请求需要写入从变量 ptrQuizFragen 地址开始的内存,但是你想要写入指针所指向的位置的内存:

 memset(ptrQuizFragen, 0, maxFragen*sizeof(Fragenfeld));

另外,出于同样的原因,你可以像初始化 ptrQuizFragen 一样完全不使用它:

memset(QuizFragen, 0, maxFragen*sizeof(Fragenfeld));

此外,直接使用正在写入的对象来表达所需大小会更清晰:

memset(QuizFragen, 0, sizeof(QuizFragen));

然而,如果这是用于一次性初始化,我不会使用 memset

Fragenfeld QuizFragen[maxFragen] = {0};

虽然这是有效的带有良好定义语义的C代码,但某些编译器可能会发出警告。如果你的编译器发出了警告并且让你感到不舒服,那么另一种选择是进行一些扩展,例如:

Fragenfeld QuizFragen[maxFragen] = { { {0}, {0} } };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接