简体   繁体   中英

C issue with dynamically allocating array

The input file for my program has the first line containing an int (call it N) that will signify how many following integers there will be (each integer on a new line). Then it should read the integers into num_array and print them out. My issue is that num_array is not being allocated properly I think. The debugging statements in the code will print out 8 being the sizeof(num_array) no matter what N is.

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

int *num_array;

int main (int argc, char**argv){
    int numThreads = (int) argv[1];
    char *inputFile = argv[2];
    int N = 0;

    char line[20];
    FILE *file = fopen(inputFile, "r");

    int fileCounter = 0;

    while(fgets(line, sizeof(line), file)) {
        if (fileCounter==0){
            N = atoi(line);
            num_array = malloc(sizeof(int)*(N+1));
        }
        else{
            num_array[fileCounter-1] = atoi(line);
        }
        fileCounter++;
    }
    fclose(file);
    int i;

    printf("%d", sizeof(num_array));
    printf("\n");
    printf("\n");
    for(i = 0; i<sizeof(num_array); i++){
        printf("%d\n", num_array[i]);
    }
    return 0;
}

Input file example:

9
10
9
3
212
56
99
4
5
6

will print out:

8  
10
9
3
212
56
99
4
5

As you can see, the last element of the array is cut off (does not print 6) and it appears num_array is not being sized properly (should contain N integers with N being the int at the first line of the input file)

Many problems with your program:

  1. The first line of your main() function has a very severe mistake

     int numThreads = (int) argv[1] 

    in c casting does not convert the type, this conversion is certainly possible, but doesn't give the result you expect, you need something like this

     char *endptr; int numThreads = strtol(argv[1], &endptr, 10); if (*endptr != '\\0') { printf("`%s' cannot be converted to an integer\\n", argv[1]); return -1; } 
  2. You didn't make sure that there was a parameter provided to your program's command line, you need to check that, argc contains the number of command line arguments passed to your program + the argv[0] , so you must check

     if (argc < 2) { printf("Use: %s NumberOfThreads, where NumberOfThreads is `int'\\n", argv[0]); return -1; } 
  3. You don't check if fopen() returns NULL , that would cause more issues when you fgets() the file pointer.

  4. The sizeof operator does not give the length of an array it gives the number of bytes occupied by the array, and you variable is not an array, it's a pointer, so the sizeof operator in this case is giving the size of a pointer.

    It turns out that your file contains 9 values and in your platform the pointer size is 8 , so sizeof(num_array) is 8 which is 9 - 1 hence your are missing one value, you already have the number of elements of the array N , so use it.

  5. You never call free() .

This is a version of your code, it's fixed and it's made safer

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

int *num_array;

int main (int argc, char**argv) 
 {
    char  line[20];
    /*int   numThreads  = 1;*/
    char *inputFile   = "data.dat";
    int   N           = 0;
    int   fileCounter = 0;
    int   i           = 0;
    FILE *file = fopen(inputFile, "r");
    if (file == NULL)
        return -1;
    while (fgets(line, sizeof(line), file) != NULL)
     {
        if (fileCounter == 0)
         {
            N         = atoi(line);
            num_array = malloc((1 + N) * sizeof(int));
            if (num_array == NULL)
             {
                fclose(file);
                return -1;
             }
         }
        else
         {
            num_array[fileCounter - 1] = atoi(line);
         }
        fileCounter++;
     }
    fclose(file);

    printf("%ld", sizeof(num_array));
    printf("\n");
    printf("\n");
    for (i = 0 ; i < N ; i++)
     {
        printf("%d\n", num_array[i]);
     }
    free(num_array);
    return 0;
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM