如何正确动态分配内存?
How to correctly dynamically allocate memory?
下面的代码是根据取自该站点的示例编写的。我不明白,我做错了什么?你能帮帮我吗?
编译:
gcc -std=c11 main.c
仅打印:
Thing: Boiled buckwheat, weight: 1500
Segmentation fault
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef struct {
// Weight in grams
size_t weight;
// Name of Thing
char name[255];
} Things;
void add_new_thing(Things **things,size_t *size)
{
size_t index = *size;
if(index == 0){
(*size) = 1;
*things = (Things*)calloc((*size),sizeof(Things));
if (*things == NULL) {
fprintf(stderr, "Error: can't allocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}else{
(*size) += 1;
Things *temp = (Things*)realloc(*things,(*size)*sizeof(Things));
if(temp != NULL) {
*things = temp;
}else{
fprintf(stderr, "Error: can't reallocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Zeroing of new structure's elements
things[index]->name[0] = '[=10=]';
things[index]->weight = 0;
}
}
void another_function(Things *things,size_t *size)
{
// Add one element to the array of structures
add_new_thing(&things,size);
const char *str1 = "Boiled buckwheat";
strncpy(things[*size-1].name, str1, strlen(str1) + 1);
things[*size-1].weight = 1500;
for(size_t i = 0;i < *size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
// Add one more element to the array of structures
add_new_thing(&things,size);
const char *str2 = "A toy";
strncpy(things[*size-1].name, str2, strlen(str2) + 1);
things[*size-1].weight = 350;
// Segmentation fault is below
for(size_t i = 0;i < *size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
}
void some_function(Things *things,size_t *size)
{
// To pass the array of structures to another function
another_function(things,size);
}
int main(void)
{
// Create NULL pointer for the array of structures
Things *things = NULL;
// Add size of structures' array which will be allocated within add_new_thing() function
size_t size = 0;
// Call some function
some_function(things,&size);
// Segmentation fault is below
printf("Print results:\n");
for(size_t i = 0;i < size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
free(things);
return(EXIT_SUCCESS);
}
请记住,C 具有 按值调用,这意味着在 main
函数中,您正在传递 things
中空指针的副本至 some_function
。 main
中的实际变量不会改变。
只有在 another_function
中,您才能通过引用模拟传递,并且只有在 another_function
中,things
变量才能通过 add_new_thing
中的分配进行更新。
在您的主函数中,您将 things
的值(即 NULL
)传递给函数 some_function()
。所以这个指针没有改变,你需要传递它的地址。
printf()
调用尝试访问存储在 NULL 中的内容。 (显然这是不可能的)
真正的问题在这里
// Zeroing of new structure's elements
things[index]->name[0] = '[=10=]';
things[index]->weight = 0;
必须是
(*things)[index].name[0] = '[=11=]';
(*things)[index].weight = 0;
因为,things
不是指针的指针,只是一个指针。
您将 things
视为指向指针数组的指针,但它只是指向 [=15= 的“数组”的指针].我说“array”,因为它不是严格意义上的数组,数组在c中是不同的东西。但它的所有用途都与数组相同。
您也在 main 中创建了指针,但您从未正确使用该指针的副本,您仍然 free()
它。
尝试阅读更正后的代码,看看你是否能理解你的错误
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef struct
{
// Weight in grams
size_t weight;
// Name of Thing
char name[255];
} Things;
void add_new_thing(Things **things,size_t *size)
{
size_t index = *size;
if(index == 0)
{
(*size) = 1;
*things = (Things*)calloc((*size),sizeof(Things));
if (*things == NULL)
{
fprintf(stderr, "Error: can't allocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
else
{
(*size) += 1;
Things *temp = (Things*)realloc(*things,(*size)*sizeof(Things));
if(temp != NULL)
{
*things = temp;
}
else
{
fprintf(stderr, "Error: can't reallocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Zeroing of new structure's elements
(*things)[index].name[0] = '[=12=]';
(*things)[index].weight = 0;
}
}
void another_function(Things **things, size_t *size)
{
// Add one element to array of structures
add_new_thing(things,size);
const char *str1 = "Boiled buckwheat";
strncpy((*things)[*size-1].name, str1, strlen(str1) + 1);
(*things)[*size-1].weight = 1500;
for(size_t i = 0; i < *size; i++)
{
printf("Thing: %s, weight: %zu\n",(*things)[i].name,(*things)[i].weight);
}
// One element of array of structures was printed there
// Add new one element to array of structures
add_new_thing(things, size);
const char *str2 = "A toy";
strncpy((*things)[*size-1].name, str2, strlen(str2) + 1);
(*things)[*size-1].weight = 350;
// Segmentation fault is there
for(size_t i = 0; i < *size; i++)
{
printf("Thing: %s, weight: %zu\n",(*things)[i].name,(*things)[i].weight);
}
}
void some_function(Things **things, size_t *size)
{
// Pass array of structures to another function
another_function(things, size);
}
int main(void)
{
// Create NULL pointer for array of structures
Things *things = NULL;
// And size of structures array which will be allocated within add_new_thing() function
size_t size = 0;
// Call some function
some_function(&things, &size);
// Segmentation fault is there
printf("Print results:\n");
for(size_t i = 0; i < size; i++)
{
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
free(things);
return(EXIT_SUCCESS);
}
下面的代码是根据取自该站点的示例编写的。我不明白,我做错了什么?你能帮帮我吗?
编译:
gcc -std=c11 main.c
仅打印:
Thing: Boiled buckwheat, weight: 1500
Segmentation fault
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef struct {
// Weight in grams
size_t weight;
// Name of Thing
char name[255];
} Things;
void add_new_thing(Things **things,size_t *size)
{
size_t index = *size;
if(index == 0){
(*size) = 1;
*things = (Things*)calloc((*size),sizeof(Things));
if (*things == NULL) {
fprintf(stderr, "Error: can't allocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}else{
(*size) += 1;
Things *temp = (Things*)realloc(*things,(*size)*sizeof(Things));
if(temp != NULL) {
*things = temp;
}else{
fprintf(stderr, "Error: can't reallocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Zeroing of new structure's elements
things[index]->name[0] = '[=10=]';
things[index]->weight = 0;
}
}
void another_function(Things *things,size_t *size)
{
// Add one element to the array of structures
add_new_thing(&things,size);
const char *str1 = "Boiled buckwheat";
strncpy(things[*size-1].name, str1, strlen(str1) + 1);
things[*size-1].weight = 1500;
for(size_t i = 0;i < *size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
// Add one more element to the array of structures
add_new_thing(&things,size);
const char *str2 = "A toy";
strncpy(things[*size-1].name, str2, strlen(str2) + 1);
things[*size-1].weight = 350;
// Segmentation fault is below
for(size_t i = 0;i < *size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
}
void some_function(Things *things,size_t *size)
{
// To pass the array of structures to another function
another_function(things,size);
}
int main(void)
{
// Create NULL pointer for the array of structures
Things *things = NULL;
// Add size of structures' array which will be allocated within add_new_thing() function
size_t size = 0;
// Call some function
some_function(things,&size);
// Segmentation fault is below
printf("Print results:\n");
for(size_t i = 0;i < size;i++){
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
free(things);
return(EXIT_SUCCESS);
}
请记住,C 具有 按值调用,这意味着在 main
函数中,您正在传递 things
中空指针的副本至 some_function
。 main
中的实际变量不会改变。
只有在 another_function
中,您才能通过引用模拟传递,并且只有在 another_function
中,things
变量才能通过 add_new_thing
中的分配进行更新。
在您的主函数中,您将 things
的值(即 NULL
)传递给函数 some_function()
。所以这个指针没有改变,你需要传递它的地址。
printf()
调用尝试访问存储在 NULL 中的内容。 (显然这是不可能的)
真正的问题在这里
// Zeroing of new structure's elements
things[index]->name[0] = '[=10=]';
things[index]->weight = 0;
必须是
(*things)[index].name[0] = '[=11=]';
(*things)[index].weight = 0;
因为,things
不是指针的指针,只是一个指针。
您将 things
视为指向指针数组的指针,但它只是指向 [=15= 的“数组”的指针].我说“array”,因为它不是严格意义上的数组,数组在c中是不同的东西。但它的所有用途都与数组相同。
您也在 main 中创建了指针,但您从未正确使用该指针的副本,您仍然 free()
它。
尝试阅读更正后的代码,看看你是否能理解你的错误
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
typedef struct
{
// Weight in grams
size_t weight;
// Name of Thing
char name[255];
} Things;
void add_new_thing(Things **things,size_t *size)
{
size_t index = *size;
if(index == 0)
{
(*size) = 1;
*things = (Things*)calloc((*size),sizeof(Things));
if (*things == NULL)
{
fprintf(stderr, "Error: can't allocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
}
else
{
(*size) += 1;
Things *temp = (Things*)realloc(*things,(*size)*sizeof(Things));
if(temp != NULL)
{
*things = temp;
}
else
{
fprintf(stderr, "Error: can't reallocate memory! %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
// Zeroing of new structure's elements
(*things)[index].name[0] = '[=12=]';
(*things)[index].weight = 0;
}
}
void another_function(Things **things, size_t *size)
{
// Add one element to array of structures
add_new_thing(things,size);
const char *str1 = "Boiled buckwheat";
strncpy((*things)[*size-1].name, str1, strlen(str1) + 1);
(*things)[*size-1].weight = 1500;
for(size_t i = 0; i < *size; i++)
{
printf("Thing: %s, weight: %zu\n",(*things)[i].name,(*things)[i].weight);
}
// One element of array of structures was printed there
// Add new one element to array of structures
add_new_thing(things, size);
const char *str2 = "A toy";
strncpy((*things)[*size-1].name, str2, strlen(str2) + 1);
(*things)[*size-1].weight = 350;
// Segmentation fault is there
for(size_t i = 0; i < *size; i++)
{
printf("Thing: %s, weight: %zu\n",(*things)[i].name,(*things)[i].weight);
}
}
void some_function(Things **things, size_t *size)
{
// Pass array of structures to another function
another_function(things, size);
}
int main(void)
{
// Create NULL pointer for array of structures
Things *things = NULL;
// And size of structures array which will be allocated within add_new_thing() function
size_t size = 0;
// Call some function
some_function(&things, &size);
// Segmentation fault is there
printf("Print results:\n");
for(size_t i = 0; i < size; i++)
{
printf("Thing: %s, weight: %zu\n",things[i].name,things[i].weight);
}
free(things);
return(EXIT_SUCCESS);
}