As the title says, I'm dense. I'm trying to allocate space on the heap to store the values of an array of uint64_t. (It could be any kind of number but that's what I used to differentiate values from pointers.) I got the answer to one of my questions here. I think I understand. What I'm trying to do is get a pointer to an array of numbers, and then assign values to the array at run-time.
Edit: updated 12:15pm EST. To save people reading, I've left the original question below, and based on comments and answers narrowed down the questions to the following. This is my C code:
#include "stdafx.h"
#include <stdlib.h>
#include <stdint.h>
#define NBRPTR 3
int main()
{
uint64_t (*LngArr3)[NBRPTR]; // pointer to array of 3 uint64_t
uint64_t s; // subscript
// WHen the next line of code is not commented, I get the following message:
// Error C2440 '=': cannot convert from 'uint64_t *' to 'uint64_t (*)[3]'
// LngArr3 = (uint64_t *)calloc(NBRPTR, sizeof(LngArr3[0]));
LngArr3 = (uint64_t(*)[NBRPTR])calloc(NBRPTR, sizeof(*LngArr3)); // this compiles fine
printf("&lngarr3=%p\n", &LngArr3);
printf("LngArr3 =%p\n", LngArr3);
printf("*LngArr3=%llu\n", *LngArr3);
for (s = 0; s < NBRPTR; s++) {
// The following line causes: Error C3863 array type 'uint64_t [3]' is not assignable
// LngArr3[s] = s;
*LngArr3[s] = s;
printf("lngarr3s=%llu ", LngArr3[s]);
}
putchar('\n');
return 0;
}
My output is the following:
&lngarr3=002BFE88
Lngarr3 =0042E8C0
*LngArr3=4384960
lngarr3s=4384960 lngarr3s=4384984 lngarr3s=4385008
I have the following questions: I'm new and really don't understand: what does the cast on the calloc do? Also, the values of lngarr3 seem to be addresses separated by 24 rather than the numbers 0, 1, 2 like I'd hoped. How can I assign values at run-time to the 3 elements of the LngArr3 array? Contrary to what I've been told it doesn't make any difference if the assignment is (*LngArr3)[s] = s;
rather than the above. I've tried it both ways and the only difference is the addresses produced.
I'm running VS 2015 Community Edition; compiled in x86 mode.
===========================================================================
For historical purposes I've left the original question as follows. My Visual Studio C code is below:
#include "stdafx.h"
#include <stdlib.h>
#include <stdint.h>
#define NBRPTR 3
#define NBRSAVPTR 2
int main()
{
uint64_t (* LngArr1)[NBRPTR]; // pointer to array of 3 uint64_t
uint64_t (* LngArr2)[NBRPTR]; // pointer to array of 3 uint64_t
uint64_t * (SavPtrArr[NBRSAVPTR]); // array of 2 pointers, hopefully pointing to above
uint64_t * PtrLngArr[NBRPTR]; // array of 3 pointers to uint64_t
uint64_t s; // subscript
(uint64_t *) SavPtrArr[0] = (uint64_t *) malloc(NBRPTR * sizeof(LngArr1[0]));
printf("&savptrarr0=%p\n", &SavPtrArr[0]);
printf("savptrarr0 =%p\n", SavPtrArr[0]);
printf("*savptrarr0=%llu\n", *SavPtrArr[0]);
for (s = 0; s < NBRPTR; s++) {
// get compile time error: "uninitialized local variable 'LngArr1' used" on next 2 lines
// *LngArr1[s] = s;
// printf("%llu ", LngArr1[s]);
// get compile time warning: "'printf': %u in format string conflicts with
// argument 1 of type 'unint64_t' *" on above line
// is it trying to print an address instead of a value?
}
putchar('\n');
(uint64_t *) SavPtrArr[1] = (uint64_t *) calloc(NBRPTR, sizeof(LngArr2[0]));
printf("&savptrarr1=%p\n", &SavPtrArr[1]);
printf("savptrarr1 =%p\n", SavPtrArr[1]);
printf("*savptrarr1=%llu\n", *SavPtrArr[1]);
for (s = 0; s < NBRPTR; s++) {
// get compile time error: "uninitialized local variable 'LngArr2' used" on next 2 lines
// *LngArr2[s] = s;
// printf("%llu ", *LngArr2[s]);
}
putchar('\n');
for (s = 0; s < NBRSAVPTR; s++)
free(SavPtrArr[s]);
putchar('\n');
putchar('\n');
for (s = 0; s < NBRPTR; s++) {
// the next line gives *PtrLinArr[s] values of the same 20 digits of garbage numbers
(uint64_t *)PtrLngArr[s] = (uint64_t *)calloc(1, sizeof(PtrLngArr[0]));
// the next line gives all three *PtrLinArr[s] values of 0
// (uint64_t *)PtrLngArr[s] = (uint64_t *)calloc(NBRPTR, sizeof(PtrLngArr[0]));
printf("&ptrlngarrs=%p\n", &PtrLngArr[s]);
printf("ptrlngarrs =%p\n", PtrLngArr[s]);
printf("*ptrlngarrs=%llu\n", *PtrLngArr[s]);
putchar('\n');
free(PtrLngArr[s]);
}
return 0;
}
My results are below:
&savptrarr0=003BF6EC
savptrarr0 =004EE8B0
*savptrarr0=14829735431805717965
&savptrarr1=003BF6F0
savptrarr1 =004F0C50
*savptrarr1=0
&ptrlngarrs=003BF6D8
ptrlgnarrs =004EE8B0
*ptrlgnarrs=18302063723772116992
&ptrlngarrs=003BF6DC
ptrlgnarrs =004EE8B0
*ptrlgnarrs=18302063723772116992
&ptrlngarrs=003BF6E0
ptrlgnarrs =004EE8B0
*ptrlgnarrs=18302063723772116992
First off, I understand from this answer that I'm not supposed to cast the pointer for malloc
and calloc
, however that gives me the compile time error of C2440 '=': cannot convert from 'void *' to 'uint64_t *'
. I don't know if this is particular to Windows or Visual Studio.
Anyway, I almost understand the results. The SavPtrArr
contains 2 pointers to different addresses. The value of element 0 is garbage and element 1 is 0 because I used calloc
instead of malloc
. But what I want to do is to assign different values to the different 3 elements of LngArr1
and LngArr2
at run time (not by assigning values in the definition of the variables). I don't know how to do this because I don't understand the correct way to assign a value to a pointer to an array.
The less important question is why the 3 elements of pointers to uint64_t (PtrLngArr
) point to the same address, and why the different number of blocks on the calloc
make a difference in the values of the results. Why garbage in one case and 0 in the other case.
I hope this isn't too long, but I wanted to show the confusion I have on this, and why the results surprised me. Can anyone change the test code to show how to assign values to the 3 element arrays? Or change it to better explain how this stuff works. Thank you.
Edit: I also tried adding the following lines but it wouldn't even compile:
uint64_t (*LngArr3)[NBRPTR]; // pointer to array of 3 uint64_t
(uint64_t *)LngArr3 = (uint64_t *)calloc(NBRPTR, sizeof(LngArr3[0]));
printf("&lngarr3=%p\n", &LngArr3);
printf("LngArr3 =%p\n", LngArr3);
printf("*LngArr3=%llu\n", *LngArr3);
for (s = 0; s < NBRPTR; s++) {
LgnArr3[s] = s;
printf("lngarr3s=%llu", LngArr3[s]);
}
putchar('\n');
I got C2106 '=': left operand must be l-value
on the calloc
and somehow got C2065 'LgnArr3': undeclared identifier
on the assign of the value of LgnArr3[s]
.