c - 大小 8 的读取无效,位于 0x400886 : set_random_fill (app. c:60)

标签 c

https://en.wikipedia.org/wiki/Set_cover_problem

有一个简单的任务,但我不知道如何在 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;
  }
}

问题可能出在哪里?

最佳答案

你的 allocate_Set 函数并不像你想象的那样工作;传递的指针是按值传递的,对于函数来说是本地的。换句话说,在 main 函数中传递和声明的指针不会被该函数修改。

您有 2 个选择:

将分配的地址返回给main

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;
}

并从 main 中调用它

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;
        }
    }
}

并从 main 调用它

set_allocate(&universe, universe_size);

关于c - 大小 8 的读取无效,位于 0x400886 : set_random_fill (app. c:60),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44177610/

相关文章:

c - 测量执行时间

c - 释放多维数组 C

c - 在为链表实现追加函数时出现段错误

c - 传递一个数组作为参数

c - 在 C 中为结构分配正确的值时遇到问题

c++如何确保我的函数在被杀死之前完全执行

c - 在C文件中设置GDB断点

c - fwrite() 之后的 fread() 获取 0 个字节

c - C-在其中一个用条件变量向主线程发出信号后,如何终止所有线程?

c - 如何从C中的函数返回2个暗淡字符数组