Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何正确地动态分配内存?_C_Arrays_Struct_Segmentation Fault_Dynamic Allocation - Fatal编程技术网

C 如何正确地动态分配内存?

C 如何正确地动态分配内存?,c,arrays,struct,segmentation-fault,dynamic-allocation,C,Arrays,Struct,Segmentation Fault,Dynamic Allocation,下面的代码是从这个网站上获取的示例生成的。我不明白,我做错了什么?你能帮我一下吗 使用以下工具进行编译: gcc-std=c11 main.c 仅打印: 物品:煮荞麦,重量:1500 分段故障 #包括 #包括 #包括 #包括 类型定义结构{ //重量(克) 尺寸与重量; //事物名称 字符名[255]; }事物; 作废添加新事物(事物**事物,大小*size) { 尺寸指数=*尺寸; 如果(索引==0){ (*大小)=1; *things=(things*)calloc((*size),size

下面的代码是从这个网站上获取的示例生成的。我不明白,我做错了什么?你能帮我一下吗

使用以下工具进行编译:

gcc-std=c11 main.c

仅打印:

物品:煮荞麦,重量:1500

分段故障

#包括
#包括
#包括
#包括
类型定义结构{
//重量(克)
尺寸与重量;
//事物名称
字符名[255];
}事物;
作废添加新事物(事物**事物,大小*size)
{
尺寸指数=*尺寸;
如果(索引==0){
(*大小)=1;
*things=(things*)calloc((*size),sizeof(things));
如果(*things==NULL){
fprintf(stderr,“错误:无法分配内存!%s\n”,strerror(errno));
退出(退出失败);
}
}否则{
(*尺寸)+=1;
事物*temp=(事物*)realloc(*事物,(*大小)*大小(事物));
如果(温度!=NULL){
*事物=温度;
}否则{
fprintf(stderr,“错误:无法重新分配内存!%s\n”,strerror(errno));
退出(退出失败);
}
//新结构元素的归零
事物[index]->name[0]='\0';
事物[指数]->权重=0;
}
}
使另一个函数无效(Things*Things,size\u t*size)
{
//向结构数组中添加一个元素
添加新的东西(&东西,大小);
const char*str1=“煮荞麦”;
strncpy(things[*size-1]。名称,str1,strlen(str1)+1);
物品[*尺寸-1]。重量=1500;
对于(大小i=0;i<*size;i++){
printf(“物件:%s,重量:%zu\n”,物件[i]。名称,物件[i]。重量);
}
//向结构数组中再添加一个元素
添加新的东西(&东西,大小);
const char*str2=“玩具”;
strncpy(things[*size-1]。名称,str2,strlen(str2)+1);
东西[*尺寸-1]。重量=350;
//分段错误如下所示
对于(大小i=0;i<*size;i++){
printf(“物件:%s,重量:%zu\n”,物件[i]。名称,物件[i]。重量);
}
}
使某些函数无效(Things*Things,size\u t*size)
{
//将结构数组传递给另一个函数
另一个函数(事物、大小);
}
内部主(空)
{
//为结构数组创建空指针
Things*Things=NULL;
//添加将在Add_new_thing()函数中分配的结构数组的大小
大小\u t大小=0;
//调用一些函数
一些函数(事物和大小);
//分段错误如下所示
printf(“打印结果:\n”);
对于(大小i=0;i
请记住,C具有callby value,这意味着在
main
函数中,您正在将
things
中的空指针的副本传递给
某些函数。
main
中的实际变量不会改变


只有在
另一个\u函数中
您才会模拟按引用传递,并且只有在
另一个\u函数中
才会通过
添加新事物
中的分配更新
事物
变量。在主函数中,您正在传递
事物
的值(即
NULL
)到函数
some\u function()
。所以这个指针没有改变,你需要传递它的地址。
printf()
调用尝试访问存储为NULL的内容。(显然这是不可能的)

真正的问题就在这里

// Zeroing of new structure's elements
things[index]->name[0] = '\0';
things[index]->weight = 0;
一定是

(*things)[index].name[0] = '\0';
(*things)[index].weight = 0;
这是因为,
things
不是指针的指针,而只是一个指针

您将
事物
视为指向指针数组的指针,但它只是指向
事物
的“数组”的指针。我说“数组”,因为严格来说它不是数组,数组在c中是不同的。但它在所有方面都与数组相同

您还可以在main中创建指针,但您从未正确使用指针的副本,您仍然
free()
it

试着阅读更正后的代码,看看你是否能理解你的错误

#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] = '\0';
            (*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);
}
#包括
#包括
#包括
#包括
类型定义结构
{
//重量(克)
尺寸与重量;
//事物名称
字符名[255];
}事物;
作废添加新事物(事物**事物,大小*size)
{
尺寸指数=*尺寸;
如果(索引==0)
{
(*大小)=1;
*things=(things*)calloc((*size),sizeof(things));
如果(*things==NULL)
{
fprintf(stderr,“错误:无法分配内存!%s\n”,strerror(errno));
退出(退出失败);
}
}
其他的
{
(*尺寸)+=1;
事物*temp=(事物*)realloc(*事物,(*大小)*大小(事物));
如果(温度!=NULL)
{
*事物=温度;
}
其他的
{
fprintf(stderr,“错误:无法重新分配内存!%s\n”,strerror(errno));
退出(退出失败);
}
//新结构元素的归零
(*things)[index].name[0]='\0';
(*物)[指标].权重=0;
}
}
作废另一个函数(事物**事物,大小*size)
{
//向结构数组中添加一个元素
添加新事物(事物、大小);
const char*str1=“煮荞麦”;
strncpy((*things)[*size-1]。名称,str1,strlen(str1)+1);
(*东西)[*大小-1],重量=1500;
对于(大小i=0;i<*size;i++)
{
printf(“物体:%s,重量:%zu\n”,(*物体[i].name,(*物体[i].weight);
}
//在那里印刷了一组结构元素
//将新的一个元素添加到结构数组中
添加新事物(事物、大小);
const char*str2=“玩具”;
strncpy((*things)[*size-1]。名称,str2,strlen(str2)+1);
(*东西)[*大小-1]。重量=350;
//有什么问题吗
对于(尺寸i=0;i<*尺寸;i+
#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] = '\0';
            (*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);
}