C中Malloc的使用和指针成员错误
Use of Malloc in C and pointer member error
#include <stdio.h>
#include <stdlib.h>
struct Album {
char* title;
}
int main(){
int i, size;
struct Album* pAlbum;
printf("Enter the number of album: ");
scanf_s("%d", &size);
pAlbum = malloc(sizeof(pAlbum) * size);
for(i=0; i<size; i++) {
printf("Enter the album title: ");
scanf_s("%p", pAlbum[i].title);
}
free(pAlbum);
return 0;
}
我想让用户输入任意数量的专辑的标题。错误是 scanf 只出现一次 pAlbump[i].tittle
循环。我分配内存不正确?
pAlbum = malloc(sizeof(pAlbum) * size);
这会分配 size
指针 。但是你想分配 size
structs.
因此您的分配应该是
pAlbum = malloc(sizeof(*pAlbum) * size);
或
pAlbum = malloc(sizeof(struct Album) * size);
或
pAlbum = calloc(size, sizeof(struct Album));
处理完之后,您将需要分配内存来存储结构中的每个字符串。这将需要单独调用 malloc
.
for(i=0; i<size; i++) {
printf("Enter the album title: ");
pAlbum[i].title = malloc(...); // you need to decide how much to allocate
scanf_s("%s", pAlbum[i].title); // hmm, this simply begs a buffer overrun ...
}
然后在释放结构数组之前,您需要释放在该循环中分配的每个 title
字符串。
在语句中使用结构的数据成员标题之前
scanf_s("%p", pAlbum[i].title);
您必须分配此数据成员将指向的内存以及您要存储输入数据的位置。
并且你必须在声明中的名称 Album 之前使用标签结构
pAlbum = malloc(sizeof( struct pAlbum) * size);
而是类型说明符 "%p"
,您必须使用 %s
来输入字符串。
您有两个选择,要么将 title
成员设为固定大小的数组
struct Album {
char title[100];
}
并以这种方式使用scanf_s
scanf_s("%99s", pAlbum[i].title, _countof(pAlbum[i].title));
或者,使用 malloc
char tmp[100];
if (scanf_s("%99s", tmp, _countof(tmp)) == 1)
pAlbum[i].title = strdup(tmp);
此外,要分配 size
结构,请按照 David Heffernan 所说的进行操作。
首先,如果您不想在您的结构中添加额外的成员,那么只需将 char*
拉到外面并使用它。如果你想把类型叫做Album,你可以写成typedef char *Album;
。您正在分配内存来保存指向字符串的指针,而不是保存实际字符串的内存。你的scanf
使用了错误的格式%p
,使用%s
读取了一串字符; scanf
正在读取未分配的内存,这将导致运行时错误。
要为 n
项分配内存,请使用 calloc
(用于连续分配)。 calloc
为 n
个元素的数组分配一个内存块,每个元素 elem_size
字节长。
calloc(n, elem_size);
您应该知道每个标题有多少字节或在您的代码中使用最大字节数。有一个函数可以为您处理内存分配,但它不是标准的一部分。它被称为strdup
。
#include <stdio.h>
#include <stdlib.h>
struct Album {
char* title;
}
int main(){
int i, size;
struct Album* pAlbum;
printf("Enter the number of album: ");
scanf_s("%d", &size);
pAlbum = malloc(sizeof(pAlbum) * size);
for(i=0; i<size; i++) {
printf("Enter the album title: ");
scanf_s("%p", pAlbum[i].title);
}
free(pAlbum);
return 0;
}
我想让用户输入任意数量的专辑的标题。错误是 scanf 只出现一次 pAlbump[i].tittle
循环。我分配内存不正确?
pAlbum = malloc(sizeof(pAlbum) * size);
这会分配 size
指针 。但是你想分配 size
structs.
因此您的分配应该是
pAlbum = malloc(sizeof(*pAlbum) * size);
或
pAlbum = malloc(sizeof(struct Album) * size);
或
pAlbum = calloc(size, sizeof(struct Album));
处理完之后,您将需要分配内存来存储结构中的每个字符串。这将需要单独调用 malloc
.
for(i=0; i<size; i++) {
printf("Enter the album title: ");
pAlbum[i].title = malloc(...); // you need to decide how much to allocate
scanf_s("%s", pAlbum[i].title); // hmm, this simply begs a buffer overrun ...
}
然后在释放结构数组之前,您需要释放在该循环中分配的每个 title
字符串。
在语句中使用结构的数据成员标题之前
scanf_s("%p", pAlbum[i].title);
您必须分配此数据成员将指向的内存以及您要存储输入数据的位置。
并且你必须在声明中的名称 Album 之前使用标签结构
pAlbum = malloc(sizeof( struct pAlbum) * size);
而是类型说明符 "%p"
,您必须使用 %s
来输入字符串。
您有两个选择,要么将 title
成员设为固定大小的数组
struct Album {
char title[100];
}
并以这种方式使用scanf_s
scanf_s("%99s", pAlbum[i].title, _countof(pAlbum[i].title));
或者,使用 malloc
char tmp[100];
if (scanf_s("%99s", tmp, _countof(tmp)) == 1)
pAlbum[i].title = strdup(tmp);
此外,要分配 size
结构,请按照 David Heffernan 所说的进行操作。
首先,如果您不想在您的结构中添加额外的成员,那么只需将 char*
拉到外面并使用它。如果你想把类型叫做Album,你可以写成typedef char *Album;
。您正在分配内存来保存指向字符串的指针,而不是保存实际字符串的内存。你的scanf
使用了错误的格式%p
,使用%s
读取了一串字符; scanf
正在读取未分配的内存,这将导致运行时错误。
要为 n
项分配内存,请使用 calloc
(用于连续分配)。 calloc
为 n
个元素的数组分配一个内存块,每个元素 elem_size
字节长。
calloc(n, elem_size);
您应该知道每个标题有多少字节或在您的代码中使用最大字节数。有一个函数可以为您处理内存分配,但它不是标准的一部分。它被称为strdup
。