Why can not I print out the elements of an array in a for
-loop?
My environment is Windows 7 Maximum,
gcc (MinGW.org GCC-6.3.0-1) 6.3.0
I input the data from the prompt like 3 1 2 3
.
I can do, e.g., printf("%" PRId64 " ", marray[2])
but from the for
-loop it doesn't work.
Here is the source code:
#define __USE_MINGW_ANSI_STDIO 1
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
size_t read_size() {
size_t x;
scanf("%lu", &x);
return x;
}
int64_t read_int64() {
int64_t x;
scanf("%" SCNd64, &x);
return x;
}
int main() {
size_t *size;
*size = read_size();
int64_t *marray = malloc(sizeof(int64_t) * *size);
for (size_t i = 0; i < *size; i ) {
marray[i] = read_int64();
}
for (size_t i = 0; i < *size; i ) {
printf("%" PRId64 " ", marray[i]);
}
free(marray);
return 0;
}
CodePudding user response:
First, in main()
you have:
size_t *size; //creating an uninitialized pointer
then you call
*size = read_size();
^ (dereferencing an uninitialized pointer
which will result in undefined behavior. (read about nasal demons here. Essentially anything can happen here. On my system, it was a run-time error. ( ...Local 'size' was referenced before being initialized.
) Note: If you do not see something similar, turn on your compiler warnings.
So, as pointed out in comments, using a pointer here is not the right approach anyway...
*size = read_size();
Suggest changing the following:
size_t read_size(){
size_t x;
scanf("%lu", &x);
return x;
}
To:
size_t read_size(void){//note, its portable to include `void` in `void` prototypes
size_t x;
scanf("%zu", &x); //zu, not lu for size_t format specifier
return x;
}
Then call it like this:
//size_t* size;
size_t size = read_size();
Then also change these :
int64_t* marray = malloc(sizeof(int64_t)**size);
...
for (size_t i = 0; i < *size; i ){
to:
int64_t* marray = malloc(sizeof(int64_t) * size);
if(marray)
{//always verify successful call before attempting to use memory
...
for (size_t i = 0; i < size; i ){//removed the dereference on size
EDIT - comments indicate need to create 2D array dynamically:
comments indicate that your intention is that
int64_t* marray = malloc(sizeof(int64_t)**size);
creates a two dimension array. That statement will only create a single dimension array, and likely not of the size that you think.
In general, create a pointer to the array, then create pointers to the each column... (for example, without knowing both dimensions, the following will create both to be size
)
int rows = size
int cols = size
int64_t **marray = malloc(sizeof(int64_t) * rows*cols);
if(!marray)//handle error
{
for(int i = 0; i < cols ; i )
{
marray[i] = malloc( rows * sizeof(int64_t));
if(!marray[i]) //handle error;
}
}
This method approximates the method indicated in comments, however IMO this is not the best way. It creates non-contiguous blocks of memory for each call to malloc, and requires one call to free()
for each call to malloc()
. A much better approach is here. (Uses only one call to malloc()
/free()
to create and free a 2D array.)