0

I think my wording may not be entirely accurate but please bear with me.

What I'm trying to do is write code that allows a user to input any amount of numbers and store them in an array for use at another piece of the code. However I think I'm struggling with how to use pointers correctly in order to achieve that. Here's the code I have at the moment:

int n = 0, marks[] = {0};
while (EOF != scanf("%d", marks+n))
{
    n++;
    int marks[n]=marks;
}

int *i_p=marks;

Unfortunately I can't initialise the variable size array with my version of C ("error: variable-sized object may not be initialised") and I don't know how else to do it. What should I change and how to make this program work correctly?

Note: this question was an exercise for school and while I read some answers to other questions using calloc/malloc, we are not expected to know or use this, so I would prefer a different solution if possible.

5
  • 2
    If you can prompt the user for #items to enter up-front, then allocate based on that. Commented Jan 25, 2016 at 18:56
  • 1
    Otherwise, you will need dynamic memory allocation (malloc), and allocate a larger chunk of memory when you need to add more items to the list. Commented Jan 25, 2016 at 18:58
  • See this blog.udemy.com/vector-in-c on how to make a dynamically resizing array in C Commented Jan 25, 2016 at 19:01
  • @MMM: As a side note: variable-sized arrays cannot be initialized in any version of C. Language specification prohibits it. Commented Jan 25, 2016 at 19:30
  • @ryyker: That's exactly what I'm talking about. Again, the error message received by the OP says that VLA declaration shall not include an initializer. Language spec prohibits initializers in VLA declarations, i.e. int vla[n] = { 0 }; will not compile. (Purely as a side note, since this is not really essential to the root of the OP's problem.) Commented Jan 25, 2016 at 21:56

3 Answers 3

2

After looking at your last line - not using calloc or malloc - there are a few alternatives.

The first, and easiest alternative is to use a very big array, and stop the user from inputting more values when it is full. Odds are, if you ask your teacher "what is the maximum amount of values the user is allowed to input", they will give you a number. Use this as the size of your array.

If your teacher doesn't say, then you can ask the user at runtime. C99 introduces a thing called a Variable Length Array. This is not an array that grows when you put things in it - you specify the length, and it will stay that length for the rest of its life. But you can specify the length at runtime. So just ask the user how many entries they are going to make, and create the array to match.

Sign up to request clarification or add additional context in comments.

1 Comment

Teacher said that we can limit the array to 100 elements ,so it turns out we don't need something like a VLA. Thanks for the uh, simple but imperfect solution, I hadn't thought of that.
2

What you want is not available out of the box. You need to implement a dynamic array.

size_t marks_size = 8;
int n = 0, *marks = malloc(marks_size * sizeof(*marks)), mark;
if (!marks) abort();

while (EOF != scanf("%d", &mark))
{
    n++;
    if (n > marks_size)
    {
        marks_size *= 2;
        marks = realloc(marks, marks_size * sizeof(*marks));
        if (!marks) abort();
    }
    marks[n]=mark;
}
int *i_p=marks;

free(marks); // when you're done with the array, free the memory

Of course you can make this code better, but this is the idea.

5 Comments

Better to test against what is wanted: 1, than against one of a number of unacceptable values like EOF. while (1 == scanf("%d", &mark)).
@ryyker Variable length arrays are variable in the sense that their size can vary, depending on runtime parameters, but once the size is set, it cannot be changed.
@ryyker As soon as the execution leaves the scope in which the VLA is defined, the array no longer exists so you cannot "re-initialize" it. I really don't see what you're suggesting.
@ryyker How exactly are you proposing to solve the OP's issue? The question is about "any amount of numbers". From a user interface's point of view asking how many numbers will be entered is a bad decision and I don't think that's what the author wanted.
If I have time outside of immediate coursework I'll give this a shot!
2

C does not have arrays whose sizes vary dynamically. Even dynamically-allocated arrays have fixed size for their lifetime. C does have arrays whose (fixed) size is not known until run time. It also has arrays whose (fixed) size is determined from an associated initializer -- that's what you have in the code you present. The array you declare has length 1 because the initializer provides exactly one element.

If you cannot use dynamic allocation (malloc or calloc), and you cannot determine how long your array needs to be without reading all the elements, then there is no general solution. You need more constraints on the problem.

The best you can do in that case is declare an array that you hope will be long enough for every case the program needs to handle in practice, and to catch and reject attempts to provide more values than that. (An upper bound on the size of the problem you must handle is just the sort of added constraint that would be helpful.) Of course, in that case you must track how many elements of your array have actually been used.

By the way, the error you report arises from this line:

    int marks[n]=marks;

That's wrong at least four different ways. I'm not even positive what it's supposed to do, but maybe you mean to re-declare array marks with a larger dimension. As I already said, C does not provide for that except via dynamic allocation.

3 Comments

@ryyker, VLAs' sizes do not vary dynamically. When a function parameter or automatic variable is declared as a VLA, the different arrays that are associated with that declaration during different executions of that function may have different sizes, but none of them ever change in size.
@ryyker, The C specification is explicit here: the lifetime of each array associated with your VLA declaration lasts from the declaration until program execution leaves the declaration's scope (C2011 6.2.4/6). When execution loops back around to that declaration after leaving its scope, it is therefore necessarily a different array that is declared.
Yes, the re-declaration of marks was in hope that I could increase its size, although it was a bit of a desperate attempt there to be honest. Accepted the other answer but I gave this +1 for the explanations.

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.