2017-05-25 200 views
0

https://en.wikipedia.org/wiki/Set_cover_problem大小为8的无效读取,在0x400886:set_random_fill(app.c:60)

有简单的任务,但我不知道如何把它写正确的C89。

valgrind说有在行错误60

enter universe size: 
22 
==18369== Invalid read of size 8 
==18369== at 0x400886: set_random_fill (app.c:66) 
==18369== by 0x4007EE: main (app.c:42) 
==18369== Address 0x8 is not stack'd, malloc'd or (recently) free'd 

这里是代码(我用clang

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

typedef struct { 
    int size; 
    int *array; 
} set ; 

typedef struct { 
    int size; 
    set *array; 
} set_collection; 

void 
set_allocate(set *allocatable_set, int numbers_amount); 

void 
set_random_fill(set *initializable_set); 

void 
set_print(set *printable_set); 

int 
main(void) 
{ 
    int universe_size = 0; 
    set *universe = NULL; 

    srand((unsigned int)time(NULL)); 

    puts("enter universe size:"); 
    scanf("%d", &universe_size); 

    set_allocate(universe, universe_size); 
    set_random_fill(universe); 
    set_print(universe); 
    free(universe); 

    return 0; 
} 

void 
set_allocate(set *allocatable_set, int numbers_amount) 
{ 
    allocatable_set = malloc(sizeof(set)); 
    allocatable_set -> size = numbers_amount; 
    allocatable_set -> array = calloc(
    (unsigned long) numbers_amount, sizeof(int) 
); 
} 

void 
set_random_fill(set *initializable_set) 
{ 
    int set_element_cursor = 0; 
    int set_elements_amount = 0; 
    int *set_elements_array = NULL; 

    set_elements_array = initializable_set -> array; 
    set_elements_amount = initializable_set -> size; 

    while (set_element_cursor < set_elements_amount) { 
    set_elements_array[set_element_cursor] = rand() % 100; 
    ++set_element_cursor; 
    } 
} 

void 
set_print(set *printable_set) 
{ 
    int set_size = 0; 
    int set_element_cursor = 0; 
    int *set_elements_array = NULL; 

    set_size = printable_set -> size; 
    set_elements_array = printable_set -> array; 

    while (set_element_cursor < set_size) { 
    printf("%d ", set_elements_array[set_element_cursor]); 
    ++set_element_cursor; 
    } 
} 

哪里是什么问题?

+0

'设置*宇宙= NULL称之为;' - >'设置*宇宙= malloc的(的sizeof(组));'代替'allocatable_set = malloc的(的sizeof(集));'。 ''int * array'也需要'free''' – BLUEPIXY

+0

根据“fail fast”策略,最好在另一个函数中分配,不是吗? –

+0

你应该按照你的意愿去做。 – BLUEPIXY

回答

1

,你认为你的allocate_Set功能不起作用;传递的指针通过值传递给函数本地。换句话说,在main函数中传递和声明的指针不会被函数修改。

你有2种选择:

返回所分配的地址返回给主

set *set_allocate(int numbers_amount) 
{ 
    set *allocatable_set = malloc(sizeof(set)); 
    if (allocatable_set != NULL) 
    { 
     allocatable_set->size = numbers_amount; 
     allocatable_set->array = calloc((unsigned long) numbers_amount, sizeof(int)); 
     if (allocatable_set->array == NULL) 
     { 
      free(allocatable_set); 
      allocatable_set = NULL; 
     } 
    } 

    return allocatable_set; 
} 

,并使用双指针

从主称其为

set *universe = set_allocate(universe_size); 

void set_allocate(set **allocatable_set, int numbers_amount) 
{ 
    *allocatable_set = malloc(sizeof(set)); 
    if (*allocatable_set != NULL) 
    { 
     *allocatable_set->size = numbers_amount; 
     *allocatable_set->array = calloc((unsigned long) numbers_amount, sizeof(int)); 
     if (*allocatable_set->array == NULL) 
     { 
      free(allocatable_set); 
      *allocatable_set = NULL; 
     } 
    } 
} 

和从主

set_allocate(&universe, universe_size); 
+0

谢谢!但是,如果在自动变量已经创建,它有什么价值?为什么它不是同一个内存地址? –

+0

它是通过指针复制结构引用的功能? –

+0

@LexUshakov通过指向函数的指针,你可以在函数中引用一个内存:换句话说,我们可以说你正在传递指针指向的地址的值。但是函数内部的指针本身只是一个局部变量。 – LPs

0

C是通过逐。此代码不会改变set *指针传递的价值:

void 
set_allocate(set *allocatable_set, int numbers_amount) 
{ 
    allocatable_set = malloc(sizeof(set)); 
    allocatable_set -> size = numbers_amount; 
    allocatable_set -> array = calloc(
    (unsigned long) numbers_amount, sizeof(int) 
); 
} 

鉴于

set *universe = NULL; 

    ... 

    set_allocate(universe, universe_size); 
    set_random_fill(universe); 

universe仍然NULL呼叫到set_random_fill

事情是这样工作的:

set * 
set_allocate(int numbers_amount) 
{ 
    set *allocatable_set = malloc(sizeof(set)); 
    if (allocatable_set == NULL) 
    { 
     return(NULL); 
    } 
    allocatable_set -> size = numbers_amount; 
    allocatable_set -> array = calloc(
    (unsigned long) numbers_amount, sizeof(int) 
); 

    return(allocatable_set); 
} 

然后调用它:

set *universe = set_allocate(universe_size); 
+0

谢谢你的回答! –

+0

但是,如果在自动变量已经创建,它有什么价值?为什么它不是同一个内存地址?它是通过指针复制结构引用的功能? –

相关问题