0

I need to create a program which:

  1. initially allocate an array to read in and hold up to 5 temperatures.
  2. prompt the user to enter temperatures and type the value -100.0 when they are finished
  3. if the user fills up the array your program should dynamically allocate a new array which is double the size.
  4. copy the old values across to the new array. deallocate the old array.
  5. continue reading into the new array.
  6. print the new array out when it's done

I'm completely new to C and I'm kinda stuck. I know how to create a dynamic array, but I don't know how to create a new array which constantly grows once the old array is filled up.

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

int main(void){
    int i,k; //loop count
    int j = 5; //initial array size
    int* temp = malloc(sizeof(int)*j); 
    int* newtemp;

    for (i = 0; i < j; i++){ //loop to read in temperature
        printf("enter temperature: ");
        scanf("%d",(temp+i));
        if (i=j){
        j = j*2; //double the size of initial array
        int* newtemp = malloc(sizeof(int)*j);
        strcpy(*newtemp,temp); // copy string
        for (k = 0; k < j; k++){ //loop to read in temperature
            printf("enter temperature: ");
            scanf("%d",(temp+i+k));
            }
        }
        switch (temp[i]){
            case (-100):
            temp[i] = '\0';
            i = 5; //loop ends
            break;
        }    
    }
    return 0;
}

The error messages:

tempp.c:18:16: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
         strcpy(*newtemp,temp);
                ^
In file included from tempp.c:3:0:
/usr/include/string.h:121:14: note: expected ‘char * restrict’ but argument is of type ‘int’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^~~~~~
tempp.c:18:25: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type [-Wincompatible-pointer-types]
         strcpy(*newtemp,temp);
                         ^~~~
In file included from tempp.c:3:0:
/usr/include/string.h:121:14: note: expected ‘const char * restrict’ but argument is of type ‘int *’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)

I know that my code is messy and I really don't know the right method to reallocate a new array while it constantly grows. Please help me with this. Thank you!

12
  • 3
    You canot use strcpy to copy ints, as in strcpy(*newtemp,temp); And *newtemp is wrong. Commented May 22, 2019 at 9:57
  • 1
    Instead of strcpy, which,as @PaulOgilvie said cannot be used for copying an array of integers, you can use realloc for re-allocation. It even preserves memory contents so you do not have to copy after expanding. Commented May 22, 2019 at 9:59
  • 2
    If you are completely new to C, you should start with some even simpler programs. Commented May 22, 2019 at 10:24
  • 2
    if (i=j){ is suspicious. I'd expect if (i==j){ Commented May 22, 2019 at 10:43
  • 2
    j is a horrible name for storing array size. Ex. tempsize would be a better name. Commented May 22, 2019 at 11:03

3 Answers 3

2

How about using the realloc tool instead?

void printArray(double *array, int size){
    for(int i=0; i<size; i++){
        printf("%.1lf ", array[i]);
    }
    putchar('\n');
}

int main(void){
    int size = 5;
    double *array = malloc(size * sizeof(double)); 
    double temperature;
    int i = 0;

    while(1){
        if(temperature == -100.0)
            break;
        if(i == size){
            size *= 2;
            array = realloc(array, size * sizeof(double));
        }
        scanf("%lf", &temperature);
        array[i] = temperature;
        printArray(array, size);
        i++;
    }
    free(array);
    return 0;
}
Sign up to request clarification or add additional context in comments.

4 Comments

task is precise, to use new array, copy data, and free not used
main should be int main(void)
@PawełDymowski Well, one could say that's what realloc does internally. The task doesn't say you have to do it in three separate function calls. Tasks should let the learner improve what is asked, so that they really promote learning :-)
I suggest using void printArray(ptrdiff_t size, double array[size]) given that it represents an array: Even better with static for the size: void printArray(ptrdiff_t size, double array[static size])
0
#define INITIALSIZE 5

typedef struct 
{
    size_t size;
    size_t index;
    int data[];
}DATA_t;

DATA_t *addData(DATA_t *data, int val)
{
    if(!data)
    {
        data = malloc(INITIALSIZE * sizeof(data -> data[0]) + sizeof(*data));
        /* malloc result checks */
        data -> size = 0;
        data -> index = 0;
    }
    if((data -> index + 1) == data -> size)
    {
        size_t newsize = data -> size * 2 ;
        DATA_t *newdata = malloc(newsize * sizeof(data -> data[0]) + sizeof(*data));
        /* malloc result checks */
        memcpy(newdata, data, data -> size * sizeof(data -> data[0]) + sizeof(*data));
        newdata -> size = newsize;
        free(data);
        data = newdata;
    }
    data -> data[data -> index++] = val;
    return data;
}

usage:

DATA_t *mydata = NULL;

while(condition)
{
    mydata = addData(mydata, ReadValue());
    /* ----- */
}

5 Comments

data = malloc(5 * sizeof(data -> data[0]) + sizeof(data)); This is bugged, same bug all over the place. Instead make it a habit to write data = malloc(sizeof(*data) + sizeof(int[5]));. Size of struct plus size of array. In that order, self-documenting code.
@Lundin forgotten * I agree. But the rest you are wrong. sizeof(data -> data[0]) gives the size of the integer.
sizeof(int[5])) is not good if OP changes the type of the data. You need to replace it everythere. Imagine long long data[]; for example
@Lundin And he does not want to add the another 5 elements only to double the size
The fact remains that your coding style caused you to write a bug, so there is no arguing about how good it is. Writing correct code is always far more important than avoiding code repetition. As for maintenance, wildly changing types of structure members is not something that should be done at a whim. Especially not if the member is a flexible array member. The 5 can be replaced with a variable n.
0

You can try to declare two arrays, and switch between them, like that:

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

int main(void){

    int currentArraySize = 5;

    int* temperatures1 = malloc(sizeof(int)*currentArraySize);
    int* temperatures2 = NULL;
    int temperaturesSlot = 0;
    int temperature = 0;
    int index = 0;


    while(1){
        if (index == currentArraySize){
            switch (temperaturesSlot){
                case 0:
                    temperatures2 = malloc(sizeof(int)* 2 *currentArraySize);
                    memcpy(temperatures2, temperatures1, currentArraySize * sizeof(int));
                    free(temperatures1);
                    temperatures1 = NULL;
                    temperaturesSlot = 1;
                    break;
                case 1:
                    temperatures1 = malloc(sizeof(int)* 2 *currentArraySize);
                    memcpy(temperatures1, temperatures2, currentArraySize * sizeof(int));
                    free(temperatures2);
                    temperatures2 = NULL;
                    temperaturesSlot = 0;
                    break;
            }
            currentArraySize *= 2;
        }

        printf("enter temperature: ");
        scanf("%d",(&temperature));
        if (temperature == -100){
            break;
        }
        else if (temperaturesSlot == 0){
            temperatures1[index] = temperature;
        }
        else{
            temperatures2[index] = temperature;
        }
        ++index;
    }

    for (int i = 0; i < index; ++i){
        if (temperaturesSlot == 0){
            printf("%d, ", temperatures1[i]);
        }
        else{
            printf("%d, ", temperatures2[i]);
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.