【问题标题】:Array of Struct Pointers (C Programming) Issues结构指针数组(C 编程)问题
【发布时间】:2016-03-17 22:51:22
【问题描述】:

因此,我正在尝试弄清楚如何做一些不同的事情,但我使用 C 的工作并不多,因此非常感谢任何帮助。

typedef int data_t;

typedef struct set {
    data_t *array;
    size_t capacity;
    size_t size;
} set_t;

typedef data_t* set_i_t;

#define CLEAR -1

我已经得到了这个使用 malloc 并分配内存的方法:

int set_init( set_t *set, int capacity ){

set->array = (data_t*)malloc(capacity * sizeof(data_t));

if(set->array == NULL){
    return 1;
}
else{
    set->capacity = capacity;
    set->size = 0;
    return 0;
}
}

还有一个释放它的方法:

void set_free( set_t *set ){

free(set->array);
set->array = NULL;
set->capacity = set->size = 0;

}

在一个单独的方法中,我尝试将集合中的所有值设置为 -1(清除)

void set_clear( set_t *set){

    int i = 0;

    for (i = 0; i < set->size; i++){
        set->array = CLEAR;
    }
    set->size = 0;

}

返回集合的大小:

int set_size( set_t set ) {
    return sizeof(set->array);
}

返回容量:

int set_capacity( set_t set ) {
    int capacity = set->capacity;
    return capacity;
}

然后打印集合:

void set_print( set_t set ) {
 //Honestly don't feel like i'm ready for this one yet.
}

如果有人可以指导我完成其中的几个,或者在这些如何工作方面给我一些帮助,那就太棒了。谢谢大家!

【问题讨论】:

  • 您的问题到底是什么?您需要帮助的哪一部分以及您遇到的具体问题是什么? Stackoverflow 不是一个教程网站,最适合解决特定问题。
  • 它是否编译(我可以看到错误,但想知道你已经走了多远)。请记住,在 99% 的情况下,警告都是错误
  • set::array 是指针而不是数组。如果你希望它是动态大小的,你必须 malloc() 一些空间。如果不这样做,则应改为将其设为固定大小的数组。
  • 如果要清除集合中的值,为什么只清除与set-&gt;size 对应的值,而不是set-&gt;capacity?此外,set_clear() 不会清除 set-&gt;array 的元素,它会更改指针本身,这可能不是您想要的。
  • 还有一点,您的set_clear() 函数会反复覆盖指针,而不是它指向的数据。目前还不清楚您是要覆盖它还是释放它。 set_size() 返回指针的大小,在 amd64 上为 8 个字节,在 i386 上为 4 个字节。这几乎肯定不是你想要的。 set_capacity() 实在是太奇怪了。

标签: c arrays pointers struct


【解决方案1】:

一个好的资源是C dynamically growing array

1


您可以阅读有关 size_t 的信息。 What is size_t in C?

typedef int data_t; 
// Here you are redefining int to data_t this is then used in array.

typedef struct set {
    data_t *array;
// The address on heap where the typedef data_t is stored
    size_t capacity;
    size_t size;
} set_t;

typedef data_t* set_i_t; 
// not sure why this is here maybe you use somewhere else

#define CLEAR -1

2


set_free(set_t *set);我觉得不错。

set_init();是但不是

set_t set_init(int capacity) {
    // create it here then return it.
    set_t ret;
    ret.array = (data_t*)malloc(capacity * sizeof(data_t));
    if (ret.array == NULL) return NULL;
    ret.capacity = capacity;
    ret.size = 0;
    return ret;
}

在调用函数中

set_t A = set_init(5); 
if (A == NULL) fprintf(stderr, "could not alloc memory\n");
// :)

3


void set_clear( set_t *set){
    // you pass the address of the struct into the function. you could also use set_i_t

    //int i = 0; 
    // why do this you can do it in the for loop as you can see

    // for (i = 0; i < set->size; i++){
    for (int i = 0; i < set->size; i++){
        //set->array = CLEAR; common mistake
        // you are saying the address of the array. aka array[0]
        // this is the same as set->(array+i)
        set->array[i] = CLEAR;
    }
    set->size = 0;    
}

4 & 5


// looks good but again better ways of doing this.
set_size( set_t set ); 
set_capacity( set_t set ); 

管理内存的更好方法,例如此处的示例。 C dynamically growing array

6

阅读所有关于 printf(); http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm


void set_print( set_t set ) {
    // Here you passed the struct in plain and simple no pointer......
    // so you will use the '.' not the '->'
    // Here we can take a look at printf();
    // %d is used to print int variables.
    // to start off you know you will have to loop through the array.
    for (int i = 0; i < set.size; i++) {
        // you know the array must be at least have one item in it.
        printf("%d\n", set.array[i]);
        // using printf print the data_t aka "int" item in the array
    }
}

希望这会有所帮助。 G

【讨论】:

  • 我真的很感激你没有给我答案,而是帮助指导我。我非常感谢!再次感谢。
【解决方案2】:

在某些地方,您使用 set_t 而不是 set_t * 定义了函数参数。

您的 set_size 只会返回 array 指针的大小(即始终为 4 或 8),因此需要 set-&gt;size

另外,set_clear 不正确 [甚至无法编译]。

我添加了一些功能并实现了 [dreaded :-)] 打印功能。不用担心...

无论如何,这是更正后的代码[请原谅无偿的风格清理]:

#include <stdio.h>
#include <malloc.h>

typedef int data_t;

typedef struct set {
    data_t *array;                      // pointer to set's data
    size_t capacity;                    // total number of data slots
    size_t size;                        // number of slots currently in use
} set_t;

typedef data_t *set_i_t;

#define CLEAR -1

int
set_init(set_t *set, int capacity)
{

    set->array = (data_t *) malloc(capacity * sizeof(data_t));

    if (set->array == NULL) {
        return 1;
    }
    else {
        set->capacity = capacity;
        set->size = 0;
        return 0;
    }
}

// And a method which frees it:
void
set_free(set_t *set)
{

    free(set->array);
    set->array = NULL;
    set->capacity = set->size = 0;

}

// i'm trying to set all the values in the set to -1 (CLEAR)
void
set_clear(set_t *set)
{

    int i = 0;

    for (i = 0; i < set->size; i++) {
#if 0
        set->array = CLEAR;
#else
        set->array[i] = CLEAR;
#endif
    }
    set->size = 0;

}

// Return the Size of the set:
int
set_size(set_t *set)
{
    return set->size;
}

// Return the maximum capacity:
int
set_capacity_max(set_t *set)
{
    int capacity = set->capacity;

    return capacity;
}

// Return the remaining available capacity:
int
set_capacity_avail(set_t *set)
{
    int capacity = set->capacity - set->size;

    return capacity;
}

// add some data
void
set_append(set_t *set,int val)
{

    // NOTES:
    // (1) this does _not_ check for overflow against capacity
    // (2) when out of capacity, we might increase capacity and do a realloc
    //     on array
#if 0
    if ((set->size + 1) >= set->capacity) {
        set->capacity += 100;
        set->array = realloc(set->array,sizeof(data_t) * set->capacity);
    }
#endif

    set->array[set->size++] = val;

}

// And then print the set:
void
set_print(set_t *set)
{
    int i;
    int len;

    // Honestly don't feel like i'm ready for this one yet.
    // Relax, no worries ...

    len = 0;
    for (i = 0; i < set->size; i++) {
        len += printf(" %d",set->array[i]);
        if (len >= 72) {
            printf("\n");
            len = 0;
        }
    }

    if (len > 0)
        printf("\n");
}

int
main(void)
{
    set_t myset;

    set_init(&myset,100);

    set_append(&myset,17);
    set_append(&myset,23);
    set_append(&myset,37);

    set_print(&myset);

    set_free(&myset);

    return 0;
}

【讨论】:

  • 这对你不知道的帮助非常大。
  • 不客气。我发现 [和其他 OP 告诉我] 完全正确的代码是最好的教学方法。无论如何,你一开始就走在了正确的轨道上。顺便说一句,我忘了提到要总是使用-Wall -Werror 编译。这可以节省大量时间。
猜你喜欢
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2019-04-13
相关资源
最近更新 更多