gpt4 book ai didi

C 指针和动态分配

转载 作者:行者123 更新时间:2023-11-30 18:24:00 25 4
gpt4 key购买 nike

我现在才学习 C 语言两周,我遇到了动态分配和指针的问题,我对下面的代码有点困惑。

我试图理解读取函数是如何工作的,但 *m 让我困惑。我只是找不到使用 *m 参数的方法,还有

if((*h = (struct inhabitant *)malloc(sizeof(struct inhabitant) * (*m))) == NULL)

我简直惊呆了。

代码如下:

#include <stdlib.h>
#include "inhabitants.h"
#include "sort.h"

void read(FILE *s, struct inhabitant **h, int *m) {
int i, ntok;
struct inhabitant *tmph;

ntok = fscanf(s, "%d", m);
if(ntok != 1 || *m < 0) {
fprintf(stderr, "Unable to read file.\n");
exit(-1);
}

if((*h = (struct inhabitant *)malloc(sizeof(struct inhabitant) * (*m))) == NULL) {
fprintf(stderr, "Unable to allocate space for inhabitants.\n");
exit(-1);
}

tmph = *h;
for(i = 0; i < (*m); ++i) {
ntok = fscanf(s, "%d %s %s %d", &(tmph[i].distance), (char *)&(tmph[i].prenom), (char *)&(tmph[i].nom), (int *)&(tmph[i].zip));
if(ntok != 4) {
fprintf(stderr, "File wrongly formatted.\n");
exit(-1);
}
}

}

int compare_inhabitants_by_distance(struct inhabitant *a, struct inhabitant *b) {
if (a->distance > b->distance)
return 1;
else
return 0;
//à compléter
}

int compare_inhabitants_by_zipcode(struct inhabitant *a, struct inhabitant *b) {
if (a->enum zipcode > b->enum zipcode)
return 1;
else
return 0;
//à compléter
}

void show(int n, struct inhabitant *a) {
int i;
for(i = 0; i < n; ++i) {
printf("%d, %s, %s, %d\n", a[i].distance, a[i].prenom, a[i].nom, a[i].zip);
}
}

void printout(FILE *s, int n, struct inhabitant *a) {
int i;
for(i = 0; i < n; ++i) {
fprintf(s, "%d %s %s %d\n", a[i].distance, a[i].prenom, a[i].nom, a[i].zip);
}
}

#define PERSONS_TO_SAVE_FILE_IN "evacuation_plan0.txt"
#define PERSONS_TO_SAVE_FILE_OUT "better_evacuation_plan0.txt"

int main(int argc, char **argv) {
FILE *s;
int n;
/*For testing purpose :
struct inhabitant inhabs[] = {
{ 100, "Jean", "France", GUADELOUPE },
{ 10, "Ameni", "Braminia", STBARTH },
{ 12, "Mathieu", "Krister", GUADELOUPE },
{ 23, "Hilaire ", "Blanchi", STMARTIN }
};
n = sizeof(inhabs) / sizeof(*inhabs);*/

struct inhabitant *inhabs0;


if((s = fopen(PERSONS_TO_SAVE_FILE_IN, "r")) == NULL) {
fprintf(stderr, "Unable to open file.");
exit(-1);
}

read(s, inhabs, )

/*
A compléter :
- Lecture du fichier.
- Tris.
*/

if((s = fopen(PERSONS_TO_SAVE_FILE_OUT, "w+")) == NULL) {
fprintf(stderr, "Unable to open file.");
exit(-1);
}
printout(s, n, inhabs0);
fclose(s);

free(inhabs0);

return EXIT_SUCCESS;
}

最佳答案

在 C 中,一个 assignment是一些expression ,表达式是一种简单(而且非常常见)的 statement .

所以而不是

int a = 2+3;
if (a>4) {

你可能会编码

int a;
if ((a=2+3) > 4) {

具有相同的 semantics .

所以你的if statement类似于:

*h = (struct inhabitant *)malloc(sizeof(struct inhabitant) * (*m));
if (*h == NULL)

(像原始代码一样使用复杂的 if ,或将其分成两个语句,是可读性和品味的问题;但是,请注意 sequence points )

顺便说一句,原始代码中接下来的内容很糟糕(并且将 exit(3) 与 -1 一起使用也是很糟糕的)。你最好使用perror(3)strerror(3)errno(3)解释为什么 malloc 失败。所以我推荐一下

  { // when *h is NULL because malloc failed
fprintf(stderr,
"Unable to allocate space for %d inhabitants: %s\n",
*m, strerror(errno));
exit(EXIT_FAILURE);
}

在您的特定情况下(分配数组),我建议使用 calloc(3) (获取一些零初始化的内存区域)而不是 malloc

顺便说一句,我建议更改您的 read 函数的名称。它可能与 POSIX read 混淆。 .

不要忘记编译时包含所有警告和调试信息,因此 gcc -Wall -Wextra -gGCC (阅读 Invoking GCC )。改进您的代码以消除警告。阅读documentation在使用每个功能之前。学习use the debugger gdb 。努力避免undefined behavior ,并且非常scared其中。

另请阅读有关 C dynamic memory allocation 的更多信息, pointer aliasing , virtual address space , memory leaks , garbage collection , reference counting 。除了 gdb 调试器之外,valgrind有时也很有用。还研究现有的源代码free software (例如在 github 上),您会学到很多东西。

关于C 指针和动态分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46861394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com