Why does fopen() change the value of the element in an array? - c

int getbit(int * list, int n)
{
return (list[n / 32] >> (n % 32)) & 1;
}
void setbit(int * list, int n)
{
list[n / 32] |= 1 << (n % 32);
}
int main()
{
FILE * out;
int size = 99; //2000000000;
int root = sqrt(size);
int * list = malloc(size / 8.0); //(2*10^9)/8
memset(list, 0, sizeof list);
int i, j;
for (i = 2; i <= root; i++)
for (j = 2 * i; j < size; j += i)
setbit(list, j);
printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
out = fopen("output.txt", "w");
printf("i=%d j=%d 98=%d\n", i, j, getbit(list, 98));
/*for (i=2; i<size; i++)
if (!getbit(list, i))
fprintf(out, "%d\n", i);
fclose(out);*/
return 0;
}
Whenever I use the fopen() in between printf, the value of the third parameter changes from 1 to 0. If I comment out the line then the value is same. What might be the reason behind this?

You see undefined behavior: sizeof(list) is probably 4 or 8 bytes, depending on the architecture, so memset with zeros does not go past the forth byte. You are reading from the third 32-bit word, which came from malloc and has not been initialized by the memset yet. Moreover, you are allocating 12 bytes (size/8.0 gets converted to int; it never makes sense to pass a float or a double to malloc, because you cannot allocate fractional bytes) so accessing the 98-th bit goes past the allocated area.
You should fix these undefined behaviors: allocate enough memory by using
// count needs to be a multiple of sizeof(int)
// The math gets pretty ugly here, but it should work:
int count = sizeof(int)*(size+(8*sizeof(int))-1)/(8*sizeof(int));
int * list = malloc(count);
Then initialize the data to zero by using the proper size:
memset(list, 0, count);

You're writing in memory you do not own, that has an undefined behavior.
Firstly, you're allocating only 12 bytes here:
int* list = malloc(size / 8.0);
You should do this (just giving you the idea, I don't know how many bytes you really want to allocate..):
int* list = malloc((size / 8.0) * sizeof(*list));
Secondly, you are memsetting only 4 bytes (if you're on 32bits system) here:
memset(list, 0, sizeof list);
You should do this:
memset(list, 0, (size / 8.0) * sizeof(*list));
Finally, the only reason your call to fopen() changes things, is because fopen() allocates memory.
Good luck.

Related

realloc invalid next size for array

Hello I keep getting invalid next size when using realloc to allocate more memory to an array which im trying to add 100,000 numbers too. I dont know why because im not understanding why it wont work. My code is here below.
int main()
{
printf("starting");
int i;
int *bubbleSortArray = (int *)malloc(sizeof(int));
int numberOfElements = 0;
int randomNumber;
srand(time(NULL));
int j;
for (int j = 0; j <= 100000; j = j +1)
{
randomNumber = rand();
if(numberOfElements != 0)
{
bubbleSortArray = (int *) realloc(bubbleSortArray, numberOfElements * sizeof(int));
}
bubbleSortArray[numberOfElements] = randomNumber;
numberOfElements = numberOfElements + 1;
}
}
In the statement you need to write at least like
bubbleSortArray = (int *) realloc(bubbleSortArray, ( numberOfElements + 1 )* sizeof(int));
Otherwise this statement
bubbleSortArray[numberOfElements] = randomNumber;
invokes undefined behavior.
Also you need to use an intermediate pointer to store the return value of the call of realloc because the function can return a null pointer. In this case the previous value stored in the pointer bubbleSortArray will be lost and you will not have an access to the already allocated memory.
So it would be better to write
int *tmp = (int *) realloc(bubbleSortArray, ( numberOfElements + 1 )* sizeof(int));
if ( tmp != NULL )
{
bubbleSortArray = tmp;
}
else
{
// some other code
}
Pay attention to that these declarations
int i;
int j;
are redundant because the declared variables are not used.
Oh, this is kind of scary. I'm not sure why you're not allocating enough space up front. But this code is going to realloc 100,000 times, which is an insane thing to do. Do you know what realloc does under the hood? I'll explain.
First, it does a NEW alloc of the amount of data. So the first time you loop, numberOfElements is zero, and you use your malloc'd space. But the second time it allocates space for 2 integers, then 3 integers, then 4, et cetera.
So it allocates 8 bytes. It remembers how much it allocated last time (4 bytes -- the size of an int on most systems), and it then does a memcpy of that much space.
Then it memcpy's 8 bytes. then it memcpy's 12 bytes, and so on and so on.
Bad, bad, bad.
What most people do is keep track of two values -- the amount of space allocated (capacity) and the amount used (count or numberOfElements).
So it looks something like this:
int capacity = 16;
int *bubbleSortArray = (int *)malloc(capacity * sizeof(int));
...
if (numberOfElements >= capacity) {
// Increase capacity by whatever means you want.
// You can double it. Or you can:
capacity += 16;
bubbleSortArray = (int *) realloc(bubbleSortArray, capacity * sizeof(int));
}
Ah, and as I cut & pasted your code, I see that you used numberOfElements. So you were consistently undersizing your realloc by 1, anyway.

How many pointers are in an array of pointers

I dynamically allocated memory for 3D array of pointers. My question is how many pointers do I have? I mean, do I have X·Y number of pointers pointing to an array of double or X·Y·Z pointers pointing to a double element or is there another variant?
double*** arr;
arr = (double***)calloc(X, sizeof(double));
for (int i = 0; i < X; ++i) {
*(arr + i) = (double**)calloc(Y, sizeof(double));
for (int k = 0; k < Y; ++k) {
*(*(arr+i) + k) = (double*)calloc(Z, sizeof(double));
}
}
The code you apparently intended to write would start:
double ***arr = calloc(X, sizeof *arr);
Notes:
Here we define one pointer, arr, and set it to point to memory provided by calloc.
Using sizeof (double) with this is wrong; arr is going to point to things of type double **, so we want the size of that. The sizeof operator accepts either types in parentheses or objects. So we can write sizeof *arr to mean “the size of a thing that arr will point to”. This always gets the right size for whatever arr points to; we never have to figure out the type.
There is no need to use calloc if we are going to assign values to all of the elements. We can use just double ***arr = malloc(X * sizeof *arr);.
In C, there is no need to cast the return value of calloc or malloc. Its type is void *, and the compiler will automatically convert that to whatever pointer type we assign it to. If the compiler complains, you are probably using a C++ compiler, not a C compiler, and the rules are different.
You should check the return value from calloc or malloc in case not enough memory was available. For brevity, I omit showing the code for that.
Then the code would continue:
for (ptrdiff_t i = 0; i < X; ++i)
{
arr[i] = calloc(Y, sizeof *arr[i]);
…
}
Notes:
Here we assign values to the X pointers that arr points to.
ptrdiff_t is defined in stddef.h. You should generally use it for array indices, unless there is a reason to use another type.
arr[i] is equivalent to *(arr + i) but is generally easier for humans to read and think about.
As before sizeof *arr[i] automatically gives us the right size for the pointer we are setting, arr[i].
Finally, the … in there is:
for (ptrdiff_t k = 0; k < Y; ++k)
arr[i][k] = calloc(Z, sizeof *arr[i][k]);
Notes:
Here we assign values to the Y pointers that arr[i] points to, and this loop is inside the loop on i that executes X times, so this code assigns XY pointers in total.
So the answer to your question is we have 1 + X + XY pointers.
Nobody producing good commercial code uses this. Using pointers-to-pointers-to-pointers is bad for the hardware (meaning inefficient in performance) because the processor generally cannot predict where a pointer points to until it fetches it. Accessing some member of your array, arr[i][j][k], requires loading three pointers from memory.
In most C implementations, you can simply allocate a three-dimensional array:
double (*arr)[Y][Z] = calloc(X, sizeof *arr);
With this, when you access arr[i][j][k], the compiler will calculate the address (as, in effect, arr + (i*Y + j)*Z + k). Although that involves several multiplications and additions, they are fairly simple for modern processors and are likely as fast or faster than fetching pointers from memory and they leave the processor’s load-store unit free to fetch the actual array data. Also, when you are using the same i and/or j repeatedly, the compiler likely generates code that keeps i*Y and/or (i*Y + j)*Z around for multiple uses without recalculating them.
Well, short answer is: it is not known.
As a classic example, keep in mind the main() prototype
int main( int argc, char** argv);
argc keeps the number of pointers. Without it we do not know how many they are. The system builds the array argv, gently updates argc with the value and then launches the program.
Back to your array
double*** arr;
All you know is that
arr is a pointer.
*arr is double**, also a pointer
**arr is double*, also a pointer
***arr is a double.
What you will get in code depends on how you build this. A common way if you need an array of arrays and things like that is to mimic the system and use a few unsigned and wrap them all with the pointers into a struct like
typedef struct
{
int n_planes;
int n_rows;
int n_columns;
double*** array;
} Cube;
A CSV file for example is char ** **, a sheet workbook is char ** ** ** and it is a bit scary, but works. For each ** a counter is needed, as said above about main()
A C example
The code below uses arr, declared as double***, to
store a pointer to a pointer to a pointer to a double
prints the value using the 3 pointers
then uses arr again to build a cube of X*Y*Z doubles, using a bit of math to set values to 9XY9.Z9
the program uses 2, 3 and 4 for a total of 24 values
lists the full array
list the first and the very last element, arr[0][0][0] and arr[X-1][Y-1][Z-1]
frees the whole thing in reverse order
The code
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int n_planes;
int n_rows;
int n_columns;
double*** array;
} Cube;
int print_array(double***, int, int, int);
int main(void)
{
double sample = 20.21;
double* pDouble = &sample;
double** ppDouble = &pDouble;
double*** arr = &ppDouble;
printf("***arr is %.2ff\n", ***arr);
printf("original double is %.2ff\n", sample);
printf("*pDouble is %.2ff\n", *pDouble);
printf("**ppDouble is %.2ff\n", **ppDouble);
// but we can build a cube of XxYxZ doubles for arr
int X = 2;
int Y = 3;
int Z = 4; // 24 elements
arr = (double***)malloc(X * sizeof(double**));
// now each arr[i] must point to an array of double**
for (int i = 0; i < X; i += 1)
{
arr[i] = (double**)malloc(Y * sizeof(double*));
for (int j = 0; j < Y; j += 1)
{
arr[i][j] = (double*)malloc(Z * sizeof(double));
for (int k = 0; k < Z; k += 1)
{
arr[i][j][k] = (100. * i) + (10. * j) + (.1 * k) + 9009.09;
}
}
}
print_array(arr, X, Y, Z);
printf("\n\
Test: first element is arr[%d][%d[%d] = %6.2f (9XY9.Z9)\n\
last element is arr[%d][%d[%d] = %6.2f (9XY9.Z9)\n",
0, 0, 0, arr[0][0][0],
(X-1), (Y-1), (Z-1), arr[X-1][Y-1][Z-1]
);
// now to free this monster
for (int x = 0; x < X; x += 1)
{
for (int y = 0; y < Y; y += 1)
{
free(arr[x][y]); // the Z rows
}
free(arr[x]); // the plane Y
}
free(arr); // the initial pointer;
return 0;
}; // main()
int print_array(double*** block, int I, int J, int K)
{
for (int a = 0; a < I; a += 1)
{
printf("\nPlane %d\n\n", a);
for (int b = 0; b < J; b += 1)
{
for (int c = 0; c < K; c += 1)
{
printf("%6.2f ", block[a][b][c]);
}
printf("\n");
}
}
return 0;
}; // print_array()
The output
***arr is 20.21f
original double is 20.21f
*pDouble is 20.21f
**ppDouble is 20.21f
Plane 0
9009.09 9009.19 9009.29 9009.39
9019.09 9019.19 9019.29 9019.39
9029.09 9029.19 9029.29 9029.39
Plane 1
9109.09 9109.19 9109.29 9109.39
9119.09 9119.19 9119.29 9119.39
9129.09 9129.19 9129.29 9129.39
Test: first element is arr[0][0[0] = 9009.09 (9XY9.Z9)
last element is arr[1][2[3] = 9129.39 (9XY9.Z9)

I get a garbage value when trying to find the sum of array

I tried defining a large number by #define, that didn't work.
int main()
{
long *N;
N = (long *)malloc(10^10 * sizeof(int));
int n = 0, sum = 0;
scanf("%d", &n);
//long N = 10 ^ 10;
//int size[N];
for (int i = 0; i < n; i++) {
scanf("%lu",(N + i));
sum = sum + *(N+i);
}
printf("%d", sum);
free(N);
return (0);
}
^ is a bitwise XOR operator. The result of operator^ is the bitwise XOR value of the operands.
10^10 * sizeof(int) is 10^ (10*4) because of precedence rules and will result in 34 bytes being allocated.
And if the value of n is greater than 8, you will end up accessing memory that is out of bounds for your program in the following statement.
scanf("%lu",(N + i));
To avoid this, you can first read into n and then use malloc like this:
malloc(n * sizeof(int))
As said in the previous answer ^ is a XOR operator. I guess your intention is to allocate memory for 10 power 10 number of integers. Its physically not possible to allocate such huge memory. Try something like
N = (long *)malloc(1000 * sizeof(long));
This may work :)

Attempt to dereference a generic pointer.

I am trying to work with directly with some low level memory stuff. I am filling a buffer with some data and then copying it to a larger buffer.
I wrote this function to help with some float data:
void copy_float_buffer(void* dest, size_t dest_index, void* src,
size_t src_index, size_t num_to_copy) {
memcpy(&dest[dest_index], &src[src_index], num_to_copy * sizeof(float));
}
I currently have two different buffers and two of each type.
float buffa[12]; // i have two of these
float buffb[12]; // and two of these as well
Then have two larger buffers that will hold the those buffers back to back.
float buffera[24]; //holds 2 buffa
float bufferb[24] //holds 2 buffb
I have simple for loop that does some calculate and fills buffa and buffb then I use the copy_float_buffers command to fill in the buffers. I do it like this.
typedef struct {
float buffa[12];
float buffb[12];
} buffs;
buffs* b;
for (int j = 0; j < 2; j++) {
b = calloc(1, sizeof(buffs));
}
for (int i = 0; i < 12; i++) {
b->buffa[i] = vmathRandRange(21);
b->buffb[i] = vmathRandRange(21);
}
for (int i = 0; i < 12; i++) {
/* printf("index:%d value:%f \n", i, b->buffa[i]); */
/* b->buffa[i] = vmathRandRange(21); */
copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffa,
(sizeof(float) * i) * 12, 12);
copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffb,
(sizeof(float) * i) * 12, 12);
}
print_buffer(b->buffa, "original buffer");
print_buffer(v_buff, "vertex buffer");
print_buffer(b->buffb, "original buffer");
print_buffer2(v_buff, "vertex buffer");
the print_buffers function just loops for 0-11 or 12-22 and prints out the values.
I feel like this is a pointer math issue and I was using gdb to try and look at the code and see how it's being copied over but I get that error above.
Attempt to dereference a generic pointer.
how do I dereference pointers when stepping through code in gdb and also. I think that function to do the memory copy is setup correctly. But it seems to be only overwriting the first 12 float or first 48 bytes and not actually shifting, something like a ring buffer.
As already mentioned in comments, you can't do dest[dest_index] simply because dest is a void*
Your copy function seems strange. In the main-code you spend a lot of effort calculating byte offsets but still you use sizeof(float) inside the copy_float_buffer function. You should either write the function to use floats everywhere or bytes everywhere - that will be much easier to understand.
Since the function is called copy_float_buffer it indicates that you want to copy floats, so it should be:
void copy_float_buffer(float* dest, size_t dest_index, float* src,
size_t src_index, size_t num_to_copy) {
memcpy(&dest[dest_index], &src[src_index], num_to_copy * sizeof(float));
}
to copy num_to_copy floats. If you do like this, you need to change the way you call the function, i.e. get rid of all the byte-offset calculation. Something like:
copy_float_buffer(v_buff, 0, b->buffa, 0, 12); // Ends in v_buff[0..11]
^ ^ ^
| | Copy 12 floats
| Start offset in buffa
Start offset in v_buff
copy_float_buffer(v_buff, 12, b->buffb, 0, 12); // Ends in v_buff[12..23]
^ ^ ^
| | Copy 12 floats
| Start offset in buffb
Start offset in v_buff
The rest of your code have some issues as well:
// You loop twice but simply overwrite `b` the second time
// so you leak memory
for (int j = 0; j < 2; j++) {
b = calloc(1, sizeof(buffs));
}
// Why do you loop 12 times?
// Do you want to copy the data in to the main buffer 12 times?
for (int i = 0; i < 12; i++) {
// The two call of copy_float_buffer is identical except for buffa and buffb
// So buffb will overwrite buffa
// Probably not what you want or ...?
copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffa,
(sizeof(float) * i) * 12, 12);
copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffb,
(sizeof(float) * i) * 12, 12);
}

error: invalid operands to binary * Pointer to a pointer to a matrix

I am getting error: invalid operands to binary * on lines 13, 20, 25, 31, and 36. I'm not sure how to deal with dynamic memory allocation to a pointer to a pointer to a matrix. Also, how to store integers in a matrix like fashion with this pointer to a pointer. Also, I realize there are lots easier ways of going about this in terms of the pointers, but I have to not use any brackets and the functions inputs were supplied to me.
void read_matrices(int **A, int **B, int **C, int *m, int *n, int *p, char *file) {
FILE *fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "\n Error: file open failed for file '%s'\n\n", file);
exit(0);
}
/* read & output m, n, p */
fscanf(fp, "%d\n%d\n%d\n", m, n, p);
printf("\n m: %d\n n: %d\n p: %d\n\n", *m, *n, *p);
/* allocate memory for A and set values to null */
A = calloc(m * n, sizeof(int));
/* read A */
int i, j;
for (i = 0; i < *m; i++) {
fscanf(fp, "\n");
for (j = 0; j < *n; j++) {
fscanf(fp, "%d", *(A + i * n + j));
}
}
/* allocate memory for B and set values null */
B = calloc(n * p, sizeof(int));
/* read B */
for (i = 0; i < *n; i++) {
fscanf(fp, "\n");
for (j = 0; j < *p; j++) {
fscanf(fp, "%d", *(B + i * p + j));
}
}
/* allocate memory for C and set values null */
C = calloc(m * p, sizeof(int));
/* close FP & free allocated memory */
fclose(fp);
}
It's a bit hard to understand what you are doing in that function, but it seems you just need to better understand pointers in C.
For this line:
A = calloc(m * n, sizeof(int));
What this is doing is it is trying to multiply two pointers, but I'm assuming you want to multiply the values they point to, so you need to prefix m and n with a * to de-reference them (and get their value).
For the assignment to A, what you are trying to do right now, is assign a pointer to a "pointer to a pointer", which is impossible. You need to deference A by prefixing it with a * to get the pointer that it is pointing to, and then you also should be casting the result of calloc to (int*) to match what you are assigning to.
Example:
*A = (int*)calloc(*m * *n, sizeof(int));
The same rules apply to the other errors in the code.
Let's look at your first error. The variables involved are declared as int *m, int *n, so pointers to ints.
On line 13:
A = calloc(m * n, sizeof(int));
The error is due to m * n. You're saying multiply pointer m with pointer n. That makes no sense. What you probably mean is to multiply the values pointed to by those pointers: (*m) * (*n).
Those to be honest, I don't see why you made m and n pointers in the first place.
Also, A is declared as a pointer to a pointer. That probably means you also want *A.
I'd recommend you read up on pass-by-value vs. pass-by-address.

Resources