1

In C, I would like to have a structure which would receive, from time to time, new data of a particular kind (lets say a float value that tells the current temperature). Now the problem is that I don't know how many of such data I'll get over time (the more time the software stays open, the more data I'll receive), nor I want to limit the amount of data my structure will accept.

How can I do this in C?

To make a relation, that would be equivalent to, in C++, declare a structure with a Vector or List and continuously call vector::push_back(T) each time new data arises, being capable of doing this till all memory in the PC is consumed. Now, AFAIK, there is not container such as vector or list available in C, so how to do this?

Thanks,

Momergil

Momergil
  • 2,213
  • 5
  • 29
  • 59
  • 1
    you could implement a linked list and your own push_back function – jgelderloos Apr 14 '14 at 17:09
  • Why bother with a list. Just make an array and grow it dynamically as needed. A common strategy is to double the allocated size whenever the count equals the size. There are also external libraries that provide this kind of operation if you don't want to implement yourself – Brandin Apr 14 '14 at 17:42

3 Answers3

2

You could implement your own dynamic array. Something like this:

typedef struct {
  int *array;
  size_t used;
  size_t size;
} Array;

int initArray(Array *a, size_t initialSize) {
  a->array = (int *)malloc(initialSize * sizeof(int));
  if(!a->array)
    return -1;
  a->used = 0;
  a->size = initialSize;
  return 0;
}

int insertArray(Array *a, int element) {
  if (a->used == a->size) {
    a->size *= 2;
    int *newMemory = (int *)realloc(a->array, a->size * sizeof(int));
    if(!newMemory)
      return -1;
    a->array = newMemory;
  }
  a->array[a->used ++] = element;
  return 0;
}

void freeArray(Array *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

See this post for details.

Community
  • 1
  • 1
Yifu Wang
  • 313
  • 2
  • 9
  • You've used `realloc` incorrectly. http://stackoverflow.com/questions/1607004/does-realloc-free-the-former-buffer-if-it-fails – ooga Apr 14 '14 at 17:39
2

Here's an example I wrote up just now:

main.c

#include "queue.h"

int main() {
    vector_handle v = vector_create();

    int i;
    for (i=0; i<100; ++i)
        vector_push(v, 0.5 * i);

    for (i=0; i<vector_size(v); ++i)
        printf("data: %f\n", vector_data(v)[i]);

    vector_destroy(v);
}

queue.h

#pragma once
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct vector * vector_handle;

vector_handle vector_create();
void vector_destroy(vector_handle vector);
void vector_realloc(vector_handle vector);
size_t vector_size(vector_handle vector);
float * vector_data(vector_handle vector);
void vector_push(vector_handle vector, float data);
float vector_pop(vector_handle vector);

queue.c

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

#include "queue.h"

struct vector {
    float *data;
    size_t size;
    size_t capacity;
};

struct vector * vector_create() {
    struct vector *object = malloc(sizeof(struct vector));
    object->size = 0;
    object->capacity = 16;
    object->data = malloc(sizeof(float) * object->capacity);
    return object;
}

void vector_destroy(struct vector *object) {
    free(object->data);
    free(object);
}

void vector_realloc(struct vector *object) {
    object->capacity *= 2;
    object->data = realloc(object->data, sizeof(float) * object->capacity);
    assert(object->data);
}

size_t vector_size(struct vector *object) {
    return object->size;
}

float * vector_data(struct vector *object) {
    return object->data;
}

void vector_push(struct vector *object, float data) {
    if (object->size == object->capacity)
        vector_realloc(object);
    object->data[object->size] = data;
    object->size++;
}

float vector_pop(struct vector *object) {
    return object->data[object->size--];
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
1

This is a possible implementation of a stack. You could use your own implementation of stack and implement push, pop and number_of_element()

 typedef struct node {
        int value;
        struct node *next;
    } Node;

    typedef struct list {
        ListNode *head;
    } Stack;
tinutomson
  • 329
  • 6
  • 12