4

i was watching an exercise in my textbook that says: Create a C program that take from the keyboard an array with length "N".

The question is: In C language, how can i create an undefined length array?

Thank you all.

AngeloP
  • 45
  • 1
  • 4
  • There are no such things. Length of arrays are static, once allocated cannot be change. For a feature like that, you have to use dynamic memory allocation – Haris Nov 11 '15 at 16:29
  • 2
    @Haris Of course there are: variable length arrays. – this Nov 11 '15 at 16:30
  • @this, he is speaking about *undefined length array!* – Haris Nov 11 '15 at 16:33
  • your exercise say that you have to create an array with N elements which is not undefined: first ask to input the length and then read one by one the values from stdin. Anyway I think that the exercise mean an array of generic length. – terence hill Nov 11 '15 at 16:34
  • Type a program in C that take from the keyboard an array with length "N" and calculate the inferior number, the major number, and the arithmetic average of the array. How would you solve it? (Sorry I'm trying to translate from italian to english). – AngeloP Nov 11 '15 at 16:38
  • there are in fact two perspectives of this question. 1st) the program have to fill from the input an array that has N elements (N as a const) and do the operations ... . 2nd) the program has to create a dynamic array (VLA) and fill it from the input, then do the operations... , in my opinion it is about the first one, sins the subject is how to do calculations on it. – milevyo Nov 11 '15 at 16:46

3 Answers3

3

Do not create an array of undefined length.

After getting the needed length N, if C99 use a VLA (Variable Length Array)

int A[N];

... or allocate memory

int *A = malloc(sizeof *A * N);
...
// use A
...
free(A);

[Edit]

Good to add validation on N before proceeding. Example:

if (N <= 0 || N >= Some_Sane_Upper_Limit_Like_1000) return;
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • When i set `int A[N];` i receive an error: Use of undeclared identifier 'N'. – AngeloP Nov 11 '15 at 16:34
  • @Michelangelo Poli Either your compiler is not C99 compliant or your have not declared `N`. Suggest 2nd method. If that fails, post your code. – chux - Reinstate Monica Nov 11 '15 at 16:35
  • @Michelangelo Poli If there are code limitations, best to initially post them in the question than later on add them to the answers. – chux - Reinstate Monica Nov 11 '15 at 17:04
  • I am 100% with you regarding the check for `N < 0`, but I disagree about the checks for `N == 0` and `N >= Some_Sane_Upper_Limit_Like_1000`. I've seen such limits transform into really nasty bugs when the limit, which seemed to be insanely large to the programmer who wrote it, was surpassed by a valid use case. Now, whether you need to check for `N == 0` is entirely up to the requirements of the subsequent processing (it may be sensible, or it may be just another unrequired limitation of usecases), but I regard any arbitrary upper limits as bugs waiting to strike. – cmaster - reinstate monica Dec 27 '15 at 22:27
  • @cmaster The "validation on `N`" is primarily for the VLA and is an example meant to be tailored for the use case. I also regard _arbitrary_ upper limits as bugs. Any limit needs relevancy to the task at hand. I also regard lack of limits as hacker attacks waiting to strike. – chux - Reinstate Monica Dec 27 '15 at 22:36
  • Good point about the hacker attacks, and about the VLA part. Those are reasons why I generally prefer heap allocations over stack VLA's. Still, if you want to sanity check against those, it suffices to use limits derived from the size of the available address space. A limit like 1000 is never appropriate in my eyes, not even for a stack VLA: We generally have at least a few MiB of available stack space these days. And 1000 is definitely a limit that may easily be exceeded by unforseen usecases. – cmaster - reinstate monica Dec 27 '15 at 22:58
  • @cmaster `N == 0` must be tested because attempting to form a zero-sized VLA causes undefined behaviour. – M.M Dec 27 '15 at 23:53
  • 2
    I'd regard a stack overflow as bug waiting to strike too, so an upper limit is a good idea. Of course the code should be written so that if the input exceeds the upper limit then the program handles this situation correctly. – M.M Dec 27 '15 at 23:53
  • @cmaster C is very popular in embedded processors which are made in the 100s of millions to billions/per year in 2015. Many have nowhere near "few MiB" of space, let alone stack space. Thus the value to limit is highly dependent on the task and resources at hand. The key is how to control `N` and handle excessive array sizes. – chux - Reinstate Monica Dec 28 '15 at 02:03
2

for more information about VLA in c99 The New C:Why Variable Length Arrays?

#include <stdlib.h>


int main(){
    int n;


    printf("size of array: ");
    scanf("%d",&n);
    // limit, and erro verification omited
    int f[n],i;

    printf("\nREADING INPUT\n");    
    for(i=0;i<n;i++){
        printf("\tValue of f[%d]: ", i);
        scanf("%d",f+i);
    }

    /*
    calc_max(f,n);
    calc_min(f,n);
    calc_avg(f,n);
    */
    printf("\n\nPRINTING VALUES:\n");
    for(i=0;i<n;i++){
        printf("\tValue of f[%d]= %d \n", i,f[i]);
    }
    return 0;
}
milevyo
  • 2,165
  • 1
  • 13
  • 18
0

It is not easy to satisfy 100% your needs, but you can give it a try:

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

char *addMe(void);

int main(void){
    char *test = addMe();
    free(test);
    return 0;
}

char *addMe(void){
    unsigned int maxLength = 15;
    unsigned int i =0;

    char *name;
    int c;

    name = malloc(1);
    if(name == NULL){
        exit(1);
    }

    printf("Enter your name:>  ");

    while ((c = getchar()) != '\n' && c != EOF) {
        name[i++] = (char) c;

        if (i > maxLength) {
            printf("Names longer than %d not allowed!\n",maxLength);
            name[maxLength] = '\0';
            break;
        }else if (i < maxLength){
            name = realloc(name, maxLength + 2);
        }
    }

    name[i] = '\0';
    printf("Your name is:>  %s\nThe length is:>  %zu\n",name ,strlen(name));

    return name;
}

Output:

Enter your name:>  l
Your name is:>  l
The length is:>  1

As you probably noticed I allocated memory only for one letter, and if you need more it will be allocated to satisfy your needs. You can also with this approach to have control of a maximum size:

Enter your name:>  Michael jacksonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
Names longer than 15 not allowed!
Your name is:>  Michael jackson
The length is:>  15

Like I said, give it a try.

Michi
  • 5,175
  • 7
  • 33
  • 58
  • Shouldn't `}else if (i < sizeof(char) * 15){` be `}else if(i < maxLength){` ? – stek29 Dec 27 '15 at 21:28
  • @stek29 you are a funny guy :)) Why should be `else if(i < maxLength)`? Both are OK. `(i < sizeof(char) * 15)` is the same as `(i < maxLength)` in my Example. I had my reasons why I used `(i < sizeof(char) * 15)` – Michi Dec 27 '15 at 21:31
  • could you please explain me why you used it? I'm just trying to learn) – stek29 Dec 27 '15 at 21:35
  • 1
    Note: sizeof(char) is by definition 1, so using it is generally redundant. – hyde Dec 27 '15 at 21:39
  • Also, this code seems to make no sense... Why realloic on every iteration of input loop, ans why to 30nwhen max length seems to be 15? – hyde Dec 27 '15 at 21:45
  • @hyde It was just to make the OP to understand how works. If you ask why I used `30` instead of `15`, well i think because I used maxlength=30 at that time, then edited. I don't remember any more. – Michi Dec 27 '15 at 21:55
  • @hyde Just because this code doesn't make sense for your, doesn't make it wrong. Did you down voted me ? – Michi Dec 27 '15 at 21:56
  • How is this program related to the question? – Bob__ Dec 27 '15 at 22:04
  • @Bob__ The Question was => `The question is: In C language, how can i create an undefined length array` – Michi Dec 27 '15 at 22:07
  • @Michi that valgrind output looks like classic off-by-one buffer overrun... If maxlength 15 means 15 printable characters, array size needs to be 16 to have room for NUL char. – hyde Dec 27 '15 at 22:10
  • For a reasonable (disclaimer: I did not actually run it) realloc exexample, here's one: http://stackoverflow.com/a/9982882/1717300 – hyde Dec 27 '15 at 22:30
  • @hyde I do understand that. Me, I was just gave him an Example. What i don't understand is: what's wrong with my code? :D – Michi Dec 27 '15 at 22:35
  • As it is now, it still seems to call realloc on every iteration (when i = 0...14). It works, because realloc with no size change just doesn't do anything, but callimg funtions for no reason isn't very good. It should call realloc only when it actually needs to change the size of allocated memory block. – hyde Dec 28 '15 at 05:05