I have been trying to make tree which has exactly 9 children of which some are uninitialized, so practically it is a tree of variable number of children. The indices of the children which are initialized are put in an array which has the size of the number of children that the tree node is supposed to have. And while freeing the whole tree of its memory allocation, I wanted to free that array, too, but I have encountered a problem which is that for some reason there is an error when I try to do so. Here is the code snippet which is fully executable after compilation, though, if someone would be so nice to help debug it for me.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct moveNode
{
int rating;
// char player;
int numPossibleMoves, *possibleMoves;
struct moveNode **children;
};
struct moveNode *moveTreeHead;
struct moveNode *createHeadNode(void);
void initializeNode(struct moveNode *node, char *boardState);
int main()
{
moveTreeHead = createHeadNode();
printf("moveTreeHead->possibleMoves[1] %d\n", moveTreeHead->possibleMoves[1]);
free(moveTreeHead->possibleMoves);
}
void initializeNode(struct moveNode *node, char *boardState)
{
int i, possibleMovesCounter = -1;
node->numPossibleMoves = 0;
for (i = 0; i < 9; i++)
{
if (boardState[i] != 'x' && boardState[i] != 'o')
{
node->numPossibleMoves++;
}
}
if (node->numPossibleMoves != 0)
{
node->possibleMoves = (int *)malloc(sizeof *(node->possibleMoves));
for (i = 0; i < 9; i++)
{
if (boardState[i] != 'x' && boardState[i] != 'o')
{
possibleMovesCounter++;
node->possibleMoves[possibleMovesCounter] = i;
node->children[i] = (struct moveNode *)malloc(sizeof *(node->children[i]));
node->children[i]->numPossibleMoves = 0;
}
}
}
else
{
node->possibleMoves = NULL;
}
}
struct moveNode *createHeadNode()
{
struct moveNode *ret = (struct moveNode *)malloc(sizeof(struct moveNode));
ret->children = (struct moveNode **)malloc(sizeof *(ret->children) * 9);
initializeNode(ret, "012345678");
return ret;
}
I get the following debugging error message:
warning: HEAP[helloworld.exe]:
warning: Heap block at 0000028AA9C23530 modified at 0000028AA9C23544 past requested size of 4
Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffa1046a773 in ntdll!RtlRegisterSecureMemoryCacheCallback () from C:\WINDOWS\SYSTEM32\ntdll.dll
What exactly does that mean? All I am trying to do is to free an integer array which has been properly allocated with malloc. What is the problem here? And I even tested out that there is no problem with the array that has been created with printf("moveTreeHead->possibleMoves[1] %d\n", moveTreeHead->possibleMoves[1]).
Edit: Problem solved, thank you!! #UnholySheep
node->possibleMoves = (int *)malloc(sizeof *(node->possibleMoves)); allocates memory for exactly one int yet you later potentially access as if it were a larger array #UnholySheep
Other:
Casts not needed in the various allocations.
Related
I'm doing dining-philosopher problem in C for assignment. And got stuck very begining of my code.
I decided each philosopher to be structure, and forks to be int array.
But I can't use global variable in this assignment.
So, I have to include shared variable in philosopher structure to pass them for arguments of thread routine.
Here is my problem - how to include int array in structure if I can't know proper size of them when initializing?
My plan is just include pointer variable in structure then allocate array's address using &.
But It doesn't work :
#include <stdlib.h>
/* inside structure*/
typedef struct s_share {
int **forks;
} t_share;
/* outside structure */
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
/* malloc structure arrary philo, size = 10 */
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
/* malloc int arrary forks, size = 100 */
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Output : segmentation fault
I tested share->forks size like this :
printf("size of forks : %ld\n", sizeof(philo->share->forks));
Output was 8.
It's enough size to store int * pointer.
Through this I know It's not the memory allocation problem.
Then what is problem? Can someone check this for me?
Edit :
When I try to malloc directly philo->share->forks, I got same error.
typedef struct s_share {
int *forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks = (int *)malloc(sizeof(int) * 100); //error
i++;
}
}
I thought it's because when philo initialized, sizeof operator calculated forks's memroy to be 8 - which required for pointer.
Is there something wrong?
Edit 2 :
To clear my question,
It's easy to solve this problem, if I write size of array in structure definition.
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
but according to my assignmet I have to get philosopher's number from cmd. So I can't do that.
Above is simple version of my origin code
Sorry, Edit 2 is wrong :
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks[i] = 1;
i++;
}
}
Output
zsh: segmentation fault ./a.out
I still got segfault when I write array size in struct definition.
I used calloc to initialize all member in my struct but same error occurs :
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)calloc(10, sizeof(t_philo));
forks = (int *)calloc(100, sizeof(int));
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Edit 4:
I finally found error. It's because I didn't malloc 'share' struct in philo struct
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share = (t_share *)malloc(sizeof(t_share)); //here
philo[i].share.forks = &forks;
i++;
}
}
That one line -allocating struct share- solved problem.
Or, I can modify philo struct definition like this :
typedef struct s_philo {
t_share share; //not pointer, just struct
} t_philo;
In this way, I can automatically malloc struct share.
I got confused in this point. Thanks for helping!
this line
philo[i].share->forks
Is dereferencing the pointer 'share' which is not set. You called malloc and did not set any values, so the data inside your allocated buffer is 'garbage' data.
// add begin
t_share* new_share = (t_share*)malloc(sizeof(t_share));
philo[i].share = new_share;
// add end
// don't use &forks
philo[i].share->forks = forks; //error
i++;
// need forks++
forks++;
Well I am wanting to change the way my structures are written, currently I use array and I need to limit its use, but I wanted a way to create a dynamic array that is the size of the reading done, without always having to edit the array value.
Current Code:
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag flag[50];
struct er_time time[50];
};
struct read_funcs
struct se_option *option;
void (*option_func) (void);
...
}
struct read_funcs func_;
struct read_funcs *func;
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
return func->option[i].flag[fg].value_flag = val;
}
void option_func(void) {
struct se_option fnc;
fnc.option = malloc(500 * sizeof(*(fnc.option)));
}
void read_fnc() {
func = &func_;
func->option = NULL;
func->option_func = option_func;
}
I look for a way to remove the array amount [50] instead each time the sr_flags function is executed the limit is raised
Example: sr_flags function executed 1x array would be [1] if executed 2x would be [2]
I also think about doing the same with the option_func function
I tried using the following more unsuccessfully
struct se_option {
struct sr_flag *flag;
struct er_time time[50];
};
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
func->option[i].flag = malloc(1 * sizeof(*(func->option[i].flag)));
return func->option[i].flag[fg].value_flag = val;
}
int main () {
for(int i < 0; i < 10; i++)
sr_flags(i, 1, 30);
return 0;
}
I'm not 100% certain on what it is you want but I think you just want to call realloc and increase the size by the amount you provide. And that's very easy to do, as for the values you want with the arrays I'm not sure so I just used a placeholder value.
#include <stdio.h>
#include <stdlib.h>
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag* flag;
struct er_time* time;
};
void allocateflags(struct se_option* options, int size, int val){
options->flag = realloc(options->flag, size*sizeof(struct sr_flag));
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
}
void allocatetime(struct se_option* options,int size, int val){
options->time = realloc(options->time, size*sizeof(struct er_time));
struct er_time* time = options->time+size-1;
time->value_time = val;
}
void displayflagvalues(struct se_option* options,int size){
for(int index = 0; index < size ; ++index){
printf("flag: %i\n",options->flag[index].value_flag);
}
}
void displaytimevalues(struct se_option* options, int size){
for(int index = 0; index < size ; ++index){
printf("time: %i\n",options->time[index].value_time);
}
}
int main(){
struct se_option options = {0};
for(int index = 0; index < 10; ++index){
allocateflags(&options, index,index);
allocatetime(&options, index,index);
}
displayflagvalues(&options, 10);
displaytimevalues(&options,10);
return 0;
}
The code creates an se_option structure wheren sr_flag and er_time pointers are null. Then there's two functions one allocateflags and the other allocatetime, both of which call realloc with the size you provide. When you call realloc, all previous memory is copied over to the new array. Also free is called automatically by realloc.
This step
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
struct er_time* time = options->time+size-1;
time->value_time = val;
Is slightly redundant but it was just to show the newest array can hold the value. If you understand pointer arithmetic, all its doing is incrementing the pointer to the last position then subtracting 1 struct size and setting that value. Basically setting the value of the final array in the pointer.
Good afternoon! This is my first post here!
I have an invalid write error when I use valgrind, but when I can figure it when I use gdb!
#include <stdio.h>
#include <stdlib.h>
#define MAX_INDEX 2
void *z_m = 0;
struct block {
struct block * suiv;
};
//Declaration of a global array
struct block * tzl[MAX_INDEX+1];
//Function used to dislay tzl in the main.
void display() {
for(int i=0; i<=MAX_INDEX; i++) {
struct bloc * tmp = tzl[i];
printf("%d => ",i);
while (tmp!=NULL) {
printf(" %li ->",(unsigned long)tmp);
tmp = tmp -> suiv;
}
printf("\n");
}
}
int main() {
z_m = (void *) malloc(1<<MAX_INDEX);
for (int i=0; i<MAX_INDEX; i++)
{
tzl[i] = NULL;
}
tzl[MAX_INDEX] = z_m;
//Here is the problem with valgrind
tzl[MAX_INDEX] -> suiv = NULL;
display();
free(z_m);
return 0;
}
What can be the problem? Thank you for answering.
You are initializing tzl[2] with a pointer to a block of 4 bytes:
tzl[MAX_INDEX] = z_m; /* z_m is malloc(4) */
But you are then treating it as a pointer to struct block:
tzl[MAX_INDEX] -> suiv = NULL;
Declare z_m as struct block * and change malloc(1<<MAX_INDEX) to malloc(sizeof(struct block)) for a start.
You should also check to make sure malloc did not return NULL, and you should probably refrain from casting malloc's return value.
I've been getting heap corruption error when calling the free() function. The project worked in VC++ 2010. The whole building process is working ok, but in run-time I get the error: (CircularQueue is name of my project)
ERRORS:
Windows has triggered a breakpoint in CircularQueue.exe.
This may be due to a corruption of the heap, which indicates a bug in
CircularQueue.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while CircularQueue.exe
has focus.
The output window may have more diagnostic information.
#include "stdafx.h"
#include<stdio.h>
#include <string.h>
#include <Windows.h>
#include "CircularQ.h"
#define max 4
//char circQ[10][3145728];
Image_details_t circQ[max],*ptr[max];
Image_details_t *temp;
LONG q[10],front=0,rear=-1;
#if 1
void main()
{
int ch;
//void insert();
insert("h",1,1,1,1);
insert("h",1,1,1,1);
insert("h",1,1,1,1);
delet();
delet();
delet();
delet();
while(1);
}
#endif
void insert(char *img,int channel,int imgWidth,int imgHeight,int imgLen)
{
//int x;
//char x[20];
int l = 0;
if((front==0&&rear==max-1)||(front>0&&rear==front-1))
printf("Queue is overflow\n");
else
{
l = strlen(img);
//scanf("%d",&x);
if(rear==max-1&&front>0)
{
printf("hello i m here");
InterlockedCompareExchange( &rear,0,rear);
circQ[rear].img = (char *) malloc(1);
strcpy(circQ[rear].img,img);
circQ[rear].channel = channel;
circQ[rear].imgWidth = imgWidth;
circQ[rear].imgHeight = imgHeight;
circQ[rear].imgLen = imgLen;
//q[rear]=x;
}
else
{
if((front==0&&rear==-1)||(rear!=front-1))
{
InterlockedExchangeAdd(&rear,1);
circQ[rear].img = (char *)malloc(l);
strcpy(circQ[rear].img,img);
circQ[rear].channel = channel;
circQ[rear].imgWidth = imgWidth;
circQ[rear].imgHeight = imgHeight;
circQ[rear].imgLen = imgLen;
//q[rear]=x;
}
}
}
}
void delet()
{
char a[20];
// char *temp;
if((front==0)&&(rear==-1))
{
printf("Queue is underflow\n");
return;
//exit(0);
}
if(front==rear)
{
//a=q[front];
strcpy(a,circQ[front].img);
//temp = circQ[front];
//free(temp);
//free(circQ[rear].img);
InterlockedCompareExchange( &rear,-1,rear);
InterlockedCompareExchange( &front,0,front);
}
else
if(front==max-1)
{
//a=q[front];
strcpy(a,circQ[front].img);
//free(circQ[rear].img);
//temp = circQ[front];
//free(temp);
InterlockedCompareExchange( &front,0,front);
}
else
{
strcpy(a,circQ[front].img);
//free(circQ[rear].img);
temp = &circQ[front];
free(temp); // in this part problem is occurring
InterlockedExchangeAdd(&front,1);
//a=q[front];
}
printf("Deleted element is:%s\n",a);
free(&circQ[front]);
}
Header file:
#include <stdio.h>
#include <malloc.h>
#include <stdint.h>
typedef struct Image_details
{
char *img;
int channel;
int imgWidth;
int imgHeight;
int imgLen;
}Image_details_t;
void insert(char *img,int channel,int imgWidth,int imgHeight,int imgLen);
void delet();
You are freeing a non-heap variable, you shouldn't, remove this
free(&circQ[front]);
You allocate space for img member, just one byte, an empty string requires one byte for the terminating '\0', you then do strcpy() which is meant for strings, i.e. non-nul sequence of bytes followed by a nul, byte.
Maybe you mean
memcpy(circQ[rear].img, img, 1);
which is also the same as
circQ[rear].img[0] = img[0];
You should check the return value of malloc().
You don't need to cast the return value of malloc(), if you need to then you are using either the wrong compiler, or the wrong programming language.
I have a bit of a problem. I am barely starting out with C, (comming from a C# background) and I am having problem with double pointers.
I have a structure as follows:
#ifndef __PROCESSINFO_H
#define __PROCESSINFO_H
struct ProcessInfo
{
int ProcesId;
int Priority;
int ExecutionTime;
int EllapsedTime;
char* ProcessName;
};
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime);
void ProcessInfo_ToString(struct ProcessInfo *processInfo);
void ProcessInfo_Dispose(struct ProcessInfo *processInfo);
#endif
Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "processinfo.h"
struct ProcessInfo *ProcessInfo_Allocate(int processId, char *processName, int priority, int executionTime)
{
struct ProcessInfo *processInfo;
processInfo = (struct ProcessInfo *)malloc(sizeof(struct ProcessInfo));
processInfo->ProcessId = processId;
processInfo->ProcessName = processName;
processInfo->Priority = priority;
processInfo->ExecutionTime = executionTime;
processInfo->EllapsedTime = 0;
return processInfo;
}
void ProcessInfo_ToString(struct ProcessInfo *processInfo)
{
printf(" %6i %6i %10i %10i, %25s", processInfo->ProcessId, processInfo->Priority, processInfo->ExecutionTime, processInfo->EllapsedTime, processInfo->ProcessName);
}
void ProcessInfo_Dispose(struct ProcessInfo *processInfo)
{
if(processInfo != NULL)
{
if(processInfo->ProcessName != NULL)
{
free(processInfo->ProcessName);
}
free(processInfo);
}
}
so now I have to manage a whole lot of ProcessInfo instances. I wrote another structure which would hold a pointer to a pointer to the ProcessInfo sturcture because i thought that I can increase and decrease it in size as needed (without too much hassle);
#ifndef __SCHEDULER_H
#define __SCHEDULER_H
struct Scheduler
{
struct ProcessInfo** Processes;
};
struct Scheduler* Scheduler_Allocate(void);
#endif
So the question is how do I initialize the **Processes member inside the Scheduler_Allocate method? How do I add stuff to it?
struct Scheduler s;
s.Processes = malloc(sizeof(struct ProcessInfo*) * size);
s.Processes[0] = ProcessInfo_Allocate(...);
// Add more items:
s.Processes = realloc(malloc(sizeof(struct ProcessInfo*) * (size + 1));
s.Processes[size] = ProcessInfo_Allocate(...);
size++;
Also see my example here:
Array of C structs
You don't need a double pointer to increase/decrease the size. Just use a normal pointer and realloc.
struct ProcessInfo* processes = malloc(sizeof(struct ProcessInfo) * 2);
struct ProcessInfo* processes_tmp;
if (!processes) {
/* bail */
}
/* do whatever with processes[0] and [1] */
processes_tmp = processes;
processes = realloc(processes, sizeof(struct ProcessInfo) * 5);
if (!processes) {
free(processes_tmp);
/* bail */
}
/* processes[0] and [1] are unchanged, and [2] [3] and [4] are now valid */
Then instead of having a ProcessInfo_Allocate, you could create a ProcessInfo_Init that would do most of the same except not allocating the memory:
int ProcessInfo_Init(struct ProcessInfo *pi, int processId, char *processName, int priority, int executionTime)
{
if (!pi) {
return -1;
}
pi->ProcessId = processId;
pi->ProcessName = processName;
pi->Priority = priority;
pi->ExecutionTime = executionTime;
pi->EllapsedTime = 0;
return 0;
}
size_t size = 10;//or what ever is the number of processes
struct ProcessInfo * process = (struct ProcessInfo *)malloc(size * sizeof(struct ProcessInfo));
if(!process)
//perhaps stop program? Do something
Processes = &process;
//later on
int i;
for(i = 0; i < size; i++)
{
printf("Process id =%d",Processes[i]->ProcesId);
etc
}
Pointer to pointer is initialized as array of pointers. So call malloc(count * sizeof(ProcessInfo*)) to initialize it. This way you get array of pointers to ProcessInfo. Then call malloc(sizeof(ProcessInfo)) many times to create particular ProcessInfo structures and put pointers to them to the array.
Also, user470379 is right that you don't need pointer to pointer just to change number of items in your array. But your idea is actually not bad either, you can stay with it if you want.
Also, since you are familiar with C#, I would recommend you to start with writing something like ArrayList in C. Then you can use it in many situations (like this one).
First change your definition to:
typedef struct Scheduler {
struct ProcessInfo** Processes;
} Scheduler;
Then something like this:
Scheduler *s;
s = malloc(sizeof(Scheduler));
if (s == NULL) {
exit(-1);
}
s = memset(s, 0, sizeof(Scheduler));
/* Or enter your own memory allocation stuff here */
i = 0; /* Or use some other number */
s->Processes[i] = someProcessInfo;