Program "sometimes" crash when using free - c

My program sometimes crash, and sometimes not when im calling free() on a element from my array. The elements in the array are a struct. I'll show with some code:
//This first part might be a bit messy, and hard to understand but it is working
int main(int argc, char *argv[]){
komplexNumber komplexNumbers[antal-1];
int i;
float temp;
int realCounter=0;
int imaginarCounter=0;
int numberOfElements=6 // this variable is set by the user using scanf, and can be any number>=2. Each komplexNumber consists of two numbers (i.e 9 -3j is a complex number)
for(i=0;i<numberOfElements*2;i++){ //
printf("Enter number %i\n", i+1);
scanf("%f", &temp);
if(i%2==0){ //a complex number consts of two parts. first entered number is first part of number1, second is second part of number1, third is first part of nr 2 etc
komplexNumbers[realCounter].real=temp;
realCounter++;
}
else{
komplexNumbers[imaginarCounter].imaginar=temp;
imaginarCounter++;
}
//The struct
typedef struct komplexNumber{
float real;
float imaginar;
} komplexNumber;
//The method that mallocs memory for each element:
void calculation(float a1, float a2, float b1, float b2, komplexNumber komplexNumbers[]){
float temp1 = (a1*a2)-(b1*b2);
float temp2 = (a1*b2)+(a2*b1);
komplexNumber *k;
k=(komplexNumber*)malloc(sizeof(komplexNumber));
k->real=temp1;
k->imaginar=temp2;
komplexNumbers[0]=*k;
}
//The loop, in which im calling free each iteration:
int counter=1;
for(i=0;i<(numberOfIterations-1);i++){
a1=komplexNumbers[0].real;
b1=komplexNumbers[0].imaginar;
a2=komplexNumbers[counter].real;
b2=komplexNumbers[counter].imaginar;
calculation(a1, a2, b1, b2, komplexNumbers);
counter++;
free(komplexNumbers[counter]);
}
This program crashes sometimes, and sometimes not. I haven't been able too see a pattern why it does, but it's the free() function that causes the crash (since when I remove free and run the program with the same values, it doesn't crash). I have not been able too see a pattern in which causes the crash. It can handle negative numbers
Note: each struct element is called complexNumber, and the array is called complexNumbers (with an s:) )

There are at least a few issues:
You're always assigning komplexNumbers[0] and freeing komplexNumbers[count]
komplexNumbers[0] = *k probably means komplexNumbers is an array of structs, not an array of pointers - you're assigning a struct, not a pointer
EDIT
In light of recent code, it's easier to show you what to do than to explain what you're doing wrong. As suspected, komplexNumbers is an array of structs. In your calculation function you don't need all that malloc stuff (and consequently you don't need the free bit). Do this instead:
komplexNumbers->real = temp1;
komplexNumbers->imaginar = temp2;

Because in calculation you always set value of 0th item (by copying the value pointed by k), then you want to free unallocated array items.

I find this part of code as little messy :-
komplexNumbers[0]=*k; inside cacluation . As it will again and again set pointer to complex type only in index 0. When you try and free this While itearting in a for loop using counter it Will fail for values of counter > 0 . I guess so But it would be better
if you frame question in a nice way and post so that we can look into it`

How is komplexNumbers (the array) allocated? You can not call free on anything that has not been returned by malloc. And you're leaking memory, the memory for k is lost when returning from calculation.

Related

Program freezes when setting values in an array using for loops, C Devkitpro 3DS

For a homebrew Minecraft-like clone for the 3DS, I'm attempting to create a data struct called a Chunk that contains a position, and a 3D array of ints, where an int in the array represents a block ID.
It is defined as so:
typedef struct{
Vector3 position; //Vector3 is a struct that simply contains xyz as floats, similar to Unity
int blocks[16][128][16]; //Array of ints, each int represents a block ID
} Chunk;
In order to fill a Chunk, I have a function that takes a pointer to the variable. It is meant to fill the 'blocks' array with the block IDs it should contain.
However, this doesn't happen, and the program hangs on execution.
The function is as so:
void generate_chunk(Chunk *chunk)
{
int newBlocks[16][128][16]; //Create temp 3D array
int x,y,z; //For loop coordinate values
for(x=0; x<16; x++) { //Loop X
for(z=0; z<16; z++) { // Loop Z
for(y=0; y<128; y++) { // Loop Y
//<enum> BLOCK_GOLD_ORE = 6, as a test
newBlocks[x][y][z]=(int)BLOCK_GOLD_ORE; //Set the value in the position xyz of the array to 6
}
}
}
/* The runtime then freezes/crashes whenever the array "newBlocks" is referenced. */
printf("\x1b[14;2Hgenerate_chunk :: %i", newBlocks[0][0][0]); //Debug print //!Crashes
//! vvv Uncomment when I've solved the problem above
//! memcpy(chunk->blocks, newBlocks, sizeof(chunk->blocks)); //Copy the temp array to the struct
}
and is called like:
Chunk newChunk;
generate_chunk(&chunk);
What happens is whenever the array or any of its values are referenced hereafter, the program will hang.
Oddly, if I put the function calling behind an if statement, the program still freezes on the first frame despite it not being called at that moment.
Even more curiously, if I assign the values without for loops like this:
void generate_chunk(Chunk *chunk)
{
int newBlocks[16][128][16]; //Create temp 3D array
newBlocks[0][0][0]=(int)BLOCK_GOLD_ORE; //Set its first value to 6 (enum)
printf("\x1b[14;2Hgenerate_chunk :: %i", newBlocks[0][0][0]); //Debug print, doesnt crash anymore
}
The program no longer hangs. It seems to fail whenever I try to assign values using a for loop. I'm probably missing something obvious, but it's driven me to think that this could even be a problem with the compiler (it probably isnt)
The compiler is GCC under DEVKITPRO.
Thanks!
Okay, it seems that the 3DS does not allow 3D arrays above around [19][19][19], when all sides are equal, though that may be flexible if you make the dimensions unequal.

How to return array with only even/odd numbers and delete the unnecessary cells?

I try to get an array, an number and is_even bool variable from the user and return an only even numbers new array, else return only odd numbers array depending on is_even.
for example: the array {1,2,3,4} and is_even=1 will return {2,4} ,if is_even=0 the returned array will be {1,3}
as I get it I should allocate the array dynamically prior to passing it to a function. what I have done so far is.
I got stuck with the return. I checked whether the content pointed by p is even or odd but how do I erase cells?
#include <stdio.h>
#include <malloc.h>
int *new_array(int *p,int number,int is_even){
int j,i=0;
int counter=0;
if(is_even){
for(j=0;j<number;j++){
if(*(p+j)%2==0){
}
}
return p;
}
}
void main() {
int n,i,is_even;
int *p;
printf("enter number of elements");
scanf("%d",&n); rewind(stdin);
printf("hoose is_even 1 or 0");
scanf("%d",&is_even);rewind(stdin);
p=(int *)malloc(n* sizeof(int));
for(i=0;i<n;i++){
scanf("%d",p+i);
}
p=new_array(p,n,is_even);
for(i=0;i<n;i++){
printf("%4d",*(p+i));
}
}
Part of your problem is that you are not accounting for one of the pieces of information you need to convey to the caller: the effective number of integers in the returned array. Your print loop assumes the same number of elements as were originally read, but by the nature of the function, this will typically be too many.
You ask,
how do I erase cells?
, but "erasure" is not a thing you can do. You can overwrite array elements with different values, but you cannot make an individual array element cease to exist, especially not from the middle of an array. The usual idiom would be to put the elements you want to keep in the initial elements of either the original array or a new one, and return how many elements that is. In the case of a new array, you must also return a pointer to the (dynamically allocated) array. The function signature you present is not adequate, because it provides no good means to return the count of elements.
There is a number of ways to address that. A simple one would be to make number an in/out parameter, by passing a pointer to the number of elements instead of the number of elements value:
int *new_array(int *p, int *number, int is_even) {
// ... 'j' keeps a running count of the number of is_even elements
*number = j; // Write the final number of elements back to the caller
return p; // return the allocated array
}
The details of the implementation would need to change a bit to accommodate the change in type and usage of the number parameter, and also to fix bugs.
You might then call it like so:
p = new_array(p, &n, is_even);
... and afterward continue just as you already were doing.
You could place all of your even/odd numbers at the beginning of the array, realloc() the array for its new size, and send the value of its new length back in your return. but you will need your function to receive (int** Array) in order to change the pointer for the array
so function declaration could be int new_array(int **p ,int number ,int is_even)
The problem is not deleting the cells the problem is that when you delete them your arrays length is not the same anymore..
By the way you can also change the value of length and return the new add for the new array with int* new_array(int *p, int *number, int is_even)

Passing pointer/array to main() from a function

I’m learning functions/pointers, and having a bit of an issue. What I need to write is a C program with main() and two other functions.
Requirements:
read_funct() must allocate enough memory using malloc() to store the data.
Function prototype for read_funct must be:
int read_funct(int *data_num, double **data_vals, char *filename)
How it’s meant to work:
main() calls the first function: read_funct()
read_num() reads binary data from a file. Two values have to be extracted: the no. of values (first 4 bytes), then the values themselves (8 bytes each, so contained in the next 8*no. of values). These correspond to data_num and data_vals. They have to be printed, the program then returns to main().
main() performs operations to edit the data from the first file.
main() calls the second function: write_funct(), which writes the edited data into a new file.
Where I am:
The first function reads data_num correctly, and reads/prints data_vals. This is all working properly. However, I’m trying to print these in main() to verify that I’m performing operations on the correct data, but I can’t get it working.
Note: I’m not trying to get it working with write_funct() at the moment, just taking it step-by-step.
Here’s my current code for main():
int read_funct(int *data_num, double **data_vals, char *filename);
int main()
{
int data_num;
double **data_vals;
//Reads file using read_funct()
read_funct(&data_num, data_vals, filename);
//Check: print data_num
printf("\nCheck No. of Values: %d\n", data_num);
//Check: print data_vals
for(int i = 0; i<data_num; i++)
{
printf("%0.3lf\t", data_vals[i]);
}
return(0);
}
Here’s read_funct()
int read_funct (int *data_num, double **data_vals, char *filename)
{
FILE * fp = fopen(filename, "rb"); //Opening file
//There's code here to check valid file open
//There's code here to determine size and check valid length
//Proceed with reading data_num if file is large enough
char buffer_n[4];
fread(buffer_n, 4, 1, fp);
int res = buffer_n[0]|(buffer_n[1] << 8)|(buffer_n[2] << 16)|(buffer_n[3] << 24); //Convert endian
data_num = &res; //Passes results back to data_num
printf("Number of Data Values: %d \n", *data_num); //Printing results
//Proceeds with calculating data_vals
data_vals = malloc(8*res); //Allocating memory
fread(data_vals, 8, res, fp);
//Prints data_vals
for(int i=0; i<res; i++)
{
printf("%0.3f\t", data_vals[i]);
}
printf("\nEnd of File Read.\n\n");
fclose(fp);
free(data_vals); //Free allocated memory
return(0);
}
Desired output:
Basically, I want it to print out the values from inside read_file() and then print a check in main(), so the output will be something like:
No. of values: 3 //From printf in read_file()
2 4 6
Check No. of values: 3 //From printf in main()
2 4 6
Where I think I'm going wrong:
Fairly sure that the main issue is that I've messed up my pointers and how I've initialised things in main(). I've been trying to fix this by myself, but I think I need some more experienced help to figure this out.
I know that every malloc() call must have a subsequent free(), but I'm worried that by doing so the way that I have, maybe I've made it so that I can't retrieve it in main(). Does it instead need to have an intermediate buffer to which memory is allocated instead?
Help to get this code working would be very greatly appreciated. Thank you!
Apart from freeing the data too soon, you have another problem here:
double **data_vals;
read_funct(&data_num, data_vals, filename);
If you want data_vals to be filled (written to, modified) by a function, you must pass its address, exactly as you do with data_num.
Here is another, slightly different, explanation. You see, you declare data_vals but you don't assign a value to it - it contains garbage. So it is a non-sense to pass data_vals to any function, or use it in any expression. It has a sense instead, to assign something to it, either via direct assignment or passing its address to a function, for the function to fill the variable.
Then, your usage of data_vals depicts a vector, or an array. So you really need to declare an array with [], or may be a pointer (pointers and arrays are quite related/interchangeable in C). The logic of your main() function requires a pointer, not a pointer to pointer. Hence, this is appropriate:
double *data_vals;
The function which writes to your pointer variable, instead, needs the address of the variable to write to; in other words: a pointer to a pointer. This is why your function has this (correct) signature:
read_funct(..., double **data_vals, ...)
To understand easily, let see the other (simpler) thing you wrote correctly:
int data_num;
read_funct(&data_num, ...); // declaration: read_funct(int *data_num, ...)
You declare data_num as integer in main(); you declare read_funct() with a formal parameter of pointer to integer, then you call read_funct() passing the address of your variable data_num. Perfect. Now, do the same with the other variable, data_vals. You declare it as pointer to double, pass its address to read_funct() using the notation &data_vals, and your function read_funct() declares that parameter as a pointer to pointer to double (and writes to it using *data_vals = .... You can see the parallelism between the two variables, right?
May be I've been too pedantic, but your question was really clear and well formed, so I tried to do the same.
Yes, you are free-ing the buffer too soon. After you have freed it, there is not guarantee as to what it contains. You can free it at the end, in main.

Why will this not print?

Before you feel the need to mark this as a duplicate post, please don't. I have read all the threads on pointers, arrays, and functions I could find but almost all of them are far too advanced to be of any help to me.
I'm not getting an error, however my code will not print my array. It seems the issue here is using scanf. I don't think the values entered are actually being put into the array in main(). I've tried using pointers, but then I get the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" whenever I try to use scanf to collect user inputted values to put into the array.
What I am working on is limited to declaring my array in the main() function, but all the operations are to be performed in promptData() function. Any help would be great, I'm at my wits end trying to figure this out on my own.
#import <stdio.h>
void promptData(double data[], int numElem);
int main(int argc, const char * argv[])
{
int size, i;
double array[size];
promptData(array, size);
for (i = 0; i < size; i++)
printf("%.2lf\n", array[i]);
return 0;
}
void promptData(double data[], int numElem)
{
int i;
printf("Enter integer values for size of array.\n");
scanf("%i", &numElem);
for (i = 0; i < numElem; i++)
{
printf("Enter array values.\n");
scanf("%lf", &data[i]);
}
}
Your program has undefined behaviour because variable size was not initialized and has indeterminate value.
You should at first in main ask the user to enter the size of the array then define the array itself and only after that fill it with values.
For example
int main(int argc, const char * argv[])
{
int size = 0;
printf( "Enter a positive integer value for the size of the array: ");
scanf( "%i", &size);
if ( size == 0 ) exit( 1 );
double array[size];
promptData(array, size);
//...
Also in C there is no such a directive as
#import <stdio.h>
Use instead
#include <stdio.h>
At least in ANSI C 89 and C 90, you can't give a variable as the size of an array. The size of array should be known at compile time. You should be doing something like double array[size];.
Even in C99, where you can have variable sized arrays; the variables should contain proper index values at the time you declare the array. In that case, you should read the number from stdin and then declare the array.
Also in C, all parameters are passed by value. This means every function takes a copy of the parameters in the function. If you want to modify a variable's value, you should pass a pointer to it, and then modify the pointer's dereferenced value, something like:
void change(int *x)
{
*x = 7;
}
void first(void)
{
int x = 5;
change(&x);
printf("%d\n", x);
}
Adding on to the other, correct, answer by Zenith, if you want a dynamically allocated array (like you want to be able to change its size based on user input), then your only option is to use one of the memory allocation functions like malloc().
Once you actually have the size in your main function, declare your array like this:
int *myArray = malloc(sizeof(int) * size));//note that malloc will return a NULL if it fails
//you should always check
if(myArray != null) {
//do stuff with myArray like you were. You can just use myArray[] as long as you
//make SURE that you don't go beyond 'size'
}
free(myArray);
//VERY important that every malloc() has a free() with it
Note: untested, but the idea is there.
Further, to answer your other question.
If you find yourself in a situation where you need to call a function and use things INSIDE that function to change stuff where you called it, you have only two choices in C.
You can either return the value and assign it to a variable in the calling function like this:
int result = myFunction(someVariable, anotherVariable);
//do stuff with result
Or, use pointers.
I'm not explaining pointers here, that's usually several lectures worth of information, and is one of the more difficult concepts to grasp for introductory programmers. All I can tell you is you need to learn them, but this format is not the right way to go about doing that.
You're passing size to promptData as a copy.
Thus changes to numElem inside promptData will not affect the size variable in your main. Hence size remains uninitialized, i.e. has an undefined value and therefore should not be used as a size for an array.
If you need to initialize an array with a size that's only known at run-time, you need to allocate memory for the array dynamically using malloc, for example:
double* array = malloc(size * sizeof(double));

Double pointer memory allocation to a struct in C

Can't find what is wrong with this code, it works as expected when inputting exactly 4 values, but on the fifth call (before it even asks for scanf) it always gives me this error:
* glibc detected ./a2: double free or corruption (fasttop): 0x0916e018 **
Here's some code of my program:
typedef struct {
int i;
char str[25];
} typeX;
int main(){
int dSize = 0;
int *dSizePtr = &dSize;
dPointer = (typeX **)malloc(sizeof(typeX *)); // makes an array of pointers
int i;
for (i = 0; i < 100; i++)
makeElement(dPointer, dSizePtr); // Puts values into those pointers
free(dPointer);
return 0;
}
void makeElement(dPointer **, int *dSizePtr){
dPointer = (typeX **)realloc(dPointer, sizeof(typeX *)*(*dSizePtr+1)); // grow the array by one
if (typeX == NULL)
return; // some kind of quit statement, just return for now
dPointer[*dSizePtr] = (typeX *)malloc(sizeof(typeX)); // make a new pointer in the array
scanf("%s", dPointer[*dSizePtr]->str); // input the values of the struct (have to use scanf)
char input[20];
scanf("%s", input);
dPointer[*dSizePtr]->int = atoi(input);
++(*dSizePtr);
}
I know I don't have to make a dSizePtr and I can just pass in &dSize, but the way my program is currently set up (this isn't exactly the same, just compressed for readability), that's the way I have to pass it.
I honestly have no idea why this error is coming up. Been looking at my code for hours and reading online and haven't found a solution. Any help will be greatly appreciated!
The problem is that your function makeElement get the value of dPointer, not its reference. When you realloc the data, the originally allocated chunk is freed. But the dPointer outside of the makeElement scope is not changed;
The runtime error is delayed as the actual memory allocation is performed in quantities bigger than sizeof(typeX*)
This line is causing the double free.
dPointer = (typeX **)realloc(dPointer, sizeof(typeX *)*(*dSizePtr+1)); // grow the array by one
For the first few iterations of the loop in the caller the block of memory is large enough that realloc() doesn't have to do anything, and thus it returns the same pointer passed to it. But at some point the block of memory is too small and realloc() has to allocate a new block of memory and returns a pointer to it. That returned pointer is assigned to dPointer in makeElement() but it does not change the value of dPointer in the caller. So the caller continues to pass the old dPointer value into makeElement(), which passes it to realloc(), which notices that this pointer has been freed (by the call to realloc() that expanded the size of the array).

Resources