So I have these three files
Main.c
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include "support.h"
int main( void ) {
int* num1 = malloc(100);
printf("num1: %p", &num1);
}
Support.c
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "support.h"
void *malloc(size_t size) {
struct block_meta *block;
if (size <= 0) {
return NULL;
}
if (!global_base) { // First call.
block = request_space(NULL, size);
if (!block) {
return NULL;
}
global_base = block;
} else {
struct block_meta *last = global_base;
block = find_free_block(&last, size);
if (!block) { // Failed to find free block.
block = request_space(last, size);
if (!block) {
return NULL;
}
} else { // Found free block
block->free = 0;
block->magic = 0x77777777;
}
}
return(block+1);
}
void free(void *ptr) {
if (!ptr) {
return;
}
struct block_meta* block_ptr = get_block_ptr(ptr);
assert(block_ptr->free == 0);
assert(block_ptr->magic == 0x77777777 || block_ptr->magic == 0x12345678);
block_ptr->free = 1;
block_ptr->magic = 0x55555555;
}
void *realloc(void *ptr, size_t size) {
if (!ptr) {
// NULL ptr. realloc should act like malloc.
return malloc(size);
}
struct block_meta* block_ptr = get_block_ptr(ptr);
if (block_ptr->size >= size) {
// We have enough space. Could free some once we implement split.
return ptr;
}
// Need to really realloc. Malloc new space and free old space.
// Then copy old data to new space.
void *new_ptr;
new_ptr = malloc(size);
if (!new_ptr) {
return NULL; // TODO: set errno on failure.
}
memcpy(new_ptr, ptr, block_ptr->size);
free(ptr);
return new_ptr;
}
void *calloc(size_t nelem, size_t elsize) {
size_t size = nelem * elsize; // TODO: check for overflow.
void *ptr = malloc(size);
memset(ptr, 0, size);
return ptr;
}
Support.h
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
struct block_meta {
size_t size;
struct block_meta *next;
int free;
int magic; // For debugging only. TODO: remove this in non-debug mode.
};
#define META_SIZE sizeof(struct block_meta)
void *global_base = NULL;
struct block_meta *find_free_block(struct block_meta **last, size_t size) {
struct block_meta *current = global_base;
while (current && !(current->free && current->size >= size)) {
*last = current;
current = current->next;
}
return current;
}
struct block_meta *request_space(struct block_meta* last, size_t size) {
struct block_meta *block;
block = sbrk(0);
void *request = sbrk(size + META_SIZE);
assert((void*)block == request); // Not thread safe.
if (request == (void*) -1) {
return NULL; // sbrk failed.
}
if (last) { // NULL on first request.
last->next = block;
}
block->size = size;
block->next = NULL;
block->free = 0;
block->magic = 0x12345678;
return block;
}
struct block_meta *get_block_ptr(void *ptr) {
return (struct block_meta*)ptr - 1;
}
However when I attempt to compile using
gcc -o asgn2 main.c support.c
I get the error
/tmp/ccscmcbS.o:(.bss+0x0): multiple definition of `global_base'
/tmp/ccyjhjQC.o:(.bss+0x0): first defined here
/tmp/ccscmcbS.o: In function `find_free_block':
support.c:(.text+0x0): multiple definition of `find_free_block'
/tmp/ccyjhjQC.o:main.c:(.text+0x0): first defined here
/tmp/ccscmcbS.o: In function `request_space':
support.c:(.text+0x55): multiple definition of `request_space'
/tmp/ccyjhjQC.o:main.c:(.text+0x55): first defined here
/tmp/ccscmcbS.o: In function `get_block_ptr':
support.c:(.text+0xfe): multiple definition of `get_block_ptr'
/tmp/ccyjhjQC.o:main.c:(.text+0xfe): first defined here
collect2: error: ld returned 1 exit status
I dont believe that I declared those methods more than once, also it is in a much different format than I am usually given. Not quite sure what it means.
The problem is that you have functions and globals defined (as opposed to declared) in your header file. Therefore, those functions are pulled into both main.c and support.c when they are compiled. Then during the linking phase, the linker sees multiple definitions.
Even if you had include guards, it wouldn't help in this case because that only defends against multiple definitions in a single compilation unit, not across multiple units.
Take the definitions of those function out of the header file, replace them with declarations, and put them either in support.c or in a separate .c file.
You can use the -fcommon option for gcc.
Make sure that the header is included only once, so add something like the following to the headers source code:
#ifndef _HAVE_SUPPORT_H
#define _HAVE_SUPPORT_H
// ...
// YOUR HEADER SOURCE CODE
// ...
#endif //_HAVE_SUPPORT_H
As I said this makes sure that the header is included only once, because then it defines _HAVE_SUPPORT_H. If now another source tries to include it, it will not do anything because _HAVE_SUPPRORT_H is already defined.
It also helps if you have only function declarations in the header and your 'real' functions will be in another *.c file.
Edit:
The second parts is the most important for your problem as #kaylum noticed
For me the solution was simple, downgrade to previous GCC version.
Here is comparison gcc installed on two different Ubuntu version.
GCC for ubuntu 20.04: https://packages.ubuntu.com/focal/gcc (gcc 9)
GCC for ubuntu 22.04: https://packages.ubuntu.com/jammy/gcc (gcc 11)
Because on my case, code was legacy code from about 20 years ago, then it makes sense for me to keep using old compiler.
Related
My arraylist implementation stop working after appending 32754 elements. I think it is very weird that this problem only occurs after appending so many elements and 32000 is still not too high to reach I know I am not checking for NULL pointer and that my test program is a infinite loop. I am using a old version to reduce the code complexity.
output:
32752
32753
32754
zsh: segmentation fault ./acl
array.c:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
union arraylist_meta {
double dummy_double;
long double dummy_long_double;
long long dummy_long_long;
void *dummy_ptr;
void (*dummy_func_ptr)(void);
struct {
size_t len;
size_t cap;
size_t sizeof_one_element;
};
};
void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element) {
union arraylist_meta *arraylist_new = malloc(array_size * sizeof_one_element + sizeof*arraylist_new);
arraylist_new->len = array_size;
arraylist_new->cap = array_size;
arraylist_new->sizeof_one_element = sizeof_one_element;
return arraylist_new+1;
}
void* acl_arraylist_append(void *arraylist_void, void *element) {
union arraylist_meta *arraylist = arraylist_void;
--arraylist;
if(arraylist->len == arraylist->cap) {
arraylist->cap = arraylist->len + 10;
arraylist = realloc(arraylist, arraylist->cap * arraylist->sizeof_one_element + sizeof *arraylist);
}
memcpy((char*)(arraylist + 1) + arraylist->sizeof_one_element * arraylist->len, element, arraylist->sizeof_one_element);
++arraylist->len;
return arraylist+1;
}
array.h:
#ifndef array_h
#define array_h
#include <stddef.h>
void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element);
void* acl_arraylist_append(void *arraylist_void, void *element_void);
#endif
a simple test programm:
#include <acl/array.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int *num = acl_arraylist_create(0, sizeof *num);
for(int i = 0;;++i) {
num = acl_arraylist_append(num, &i);
printf("%d\n", i);
}
}
Edit:
I changed the of the executable a while ago. By reverting a few commits back my build script was using the old name again, but executed the executable with name. This means that the problem I describe above does not with code above. It only occurs when using the code below:
array.c:
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <acl/array.h>
size_t acl_arraylist_len(void *arraylist);
void acl_arraylist_free(void *arraylist);
static inline void* acl_arraylist_resize(union acl_arraylist_meta *arraylist, int64_t relativLen) {
size_t cap = arraylist->cap + relativLen;
arraylist = realloc(arraylist, cap * arraylist->sizeof_one_element + sizeof *arraylist);
if(arraylist != NULL) {
arraylist->cap = cap;
}
return arraylist;
}
void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element) {
union acl_arraylist_meta *arraylist_new = malloc(array_size * sizeof_one_element + sizeof*arraylist_new);
if(arraylist_new == NULL) return NULL;
arraylist_new->len = array_size;
arraylist_new->cap = array_size;
arraylist_new->sizeof_one_element = sizeof_one_element;
return arraylist_new+1;
}
void* acl_arraylist_append(void *arraylist_void, void *element) {
void *element_append;
union acl_arraylist_meta *arraylist = acl_arraylist_append_ptr(arraylist_void, &element_append);
if(arraylist == NULL) return NULL;
--arraylist;
memcpy(element_append, element, arraylist->sizeof_one_element);
return arraylist + 1;
}
void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element) {
union acl_arraylist_meta *arraylist = arraylist_void;
--arraylist;
if(arraylist->len == arraylist->cap) {
acl_arraylist_resize(arraylist, 10);
if(arraylist == NULL) return NULL;
}
*append_element = (char*)(arraylist + 1) + arraylist->sizeof_one_element * arraylist->len;
++arraylist->len;
return arraylist + 1;
}
void* acl_arraylist_remove(void *arraylist_void, size_t index) {
union acl_arraylist_meta *arraylist = (union acl_arraylist_meta*)arraylist_void - 1;
char *arraylist_char = arraylist_void;
if(index != arraylist->len - 1) {
memcpy(arraylist_char + arraylist->sizeof_one_element * index, arraylist_char + arraylist->sizeof_one_element * (arraylist->len - 1), arraylist->sizeof_one_element);
}
--arraylist->len;
if(arraylist->len < arraylist->cap - 20) {
void* arraylistTmp = acl_arraylist_resize(arraylist, -10);
if(arraylistTmp != NULL) arraylist = arraylistTmp;
}
return arraylist + 1;
}
array.h:
#ifndef _acl_array_h
#define _acl_array_h
#include <stddef.h>
#include <stdlib.h>
union acl_arraylist_meta {
double dummy_double;
long double dummy_long_double;
long long dummy_long_long;
void *dummy_ptr;
void (*dummy_func_ptr)(void);
struct {
size_t len;
size_t cap;
size_t sizeof_one_element;
};
};
inline size_t acl_arraylist_len(void *arraylist) {
return ((union acl_arraylist_meta*)arraylist - 1)->len;
}
inline void acl_arraylist_free(void *arraylist) {
free((union acl_arraylist_meta*)arraylist-1);
}
void* acl_arraylist_remove(void *arraylist_void, size_t index);
void* acl_arraylist_create(size_t array_size, size_t sizeof_one_element);
void* acl_arraylist_append(void *arraylist_void, void *element);
void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element);
#endif
a simple test programm:
#include <acl/array.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *num = acl_arraylist_create(100, sizeof(int));
for (int i = 0; i < 65536; ++i)
{
num = acl_arraylist_append(num, &i);
printf("%d\n", i);
}
}
It's worrying that your array.c source file does not include the header (acl/array.h) that declares the services that the source file defines. It means there is no cross-checking. The headers provide the glue that holds C programs together, providing cross-checking to ensure that the code using the services provided agrees with the code providing those services.
Also: Your sample program doesn't create a list — your code should not compile because num is not defined.
When resequenced a bit, the code does compile cleanly. When I added a call:
void *num = acl_arraylist_create(100, sizeof(int));
before the loop in main() and ran the code (source code acl23.c, program acl23), I got to iteration 150 before the Mac OS library said:
acl23(54767,0x10d41b5c0) malloc: *** error for object 0x7f8c40c02bb0: pointer being realloc'd was not allocated
acl23(54767,0x10d41b5c0) malloc: *** set a breakpoint in malloc_error_break to debug.
If you've got Valgrind available to you, use it.
I think your code is playing with fire (and you're getting burnt) because you're trying to combine the union arraylist_meta structure and the array data.
However, the primary problem is that when the memory is reallocated, you are not using the new value returned by acl_arraylist_append(). Change the line in the loop to:
new = acl_arraylist_append(num, &i);
and the code runs up to 65535 for me. I set the loop to stop then, rather than imposing no limit.
for (int i = 0; i < 65536; ++i).
It isn't clear how the user of your array list is going to access elements of the array. Presumably, you plan to have them convert the void * (num in the example) to an appropriate typed pointer (int *array = num;) and they can then index into the array. It's also not clear how they determine the size of the array — what the maximum index is. You've also not provided a function to free the array. The user can't do that — the pointer they have is not the one returned by one of the allocation functions (malloc(), realloc(), etc). None of these are immediately critical; we can safely assume that they were omitted from the
MCVE (Minimal, Complete, Verifiable Example — or MRE or whatever name SO now uses) you provided.
Here's my working code derived from yours — all in a single file. The changes are actually quite minor.
/*array.h:*/
#ifndef array_h
#define array_h
#include <stddef.h>
void *acl_arraylist_create(size_t array_size, size_t sizeof_one_element);
void *acl_arraylist_append(void *arraylist_void, void *element_void);
#endif
/*array.c:*/
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
/*#include <acl/array.h>*/
union arraylist_meta
{
double dummy_double;
long double dummy_long_double;
long long dummy_long_long;
void *dummy_ptr;
void (*dummy_func_ptr)(void);
struct
{
size_t len;
size_t cap;
size_t sizeof_one_element;
};
};
void *acl_arraylist_create(size_t array_size, size_t sizeof_one_element)
{
union arraylist_meta *arraylist_new = malloc(array_size * sizeof_one_element + sizeof *arraylist_new);
arraylist_new->len = array_size;
arraylist_new->cap = array_size;
arraylist_new->sizeof_one_element = sizeof_one_element;
return arraylist_new + 1;
}
void *acl_arraylist_append(void *arraylist_void, void *element)
{
union arraylist_meta *arraylist = arraylist_void;
--arraylist;
if (arraylist->len == arraylist->cap)
{
arraylist->cap = arraylist->len + 10;
arraylist = realloc(arraylist, arraylist->cap * arraylist->sizeof_one_element + sizeof *arraylist);
}
memcpy((char *)(arraylist + 1) + arraylist->sizeof_one_element * arraylist->len, element, arraylist->sizeof_one_element);
++arraylist->len;
return arraylist + 1;
}
/*a simple test programm:*/
/*#include <acl/array.h>*/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *num = acl_arraylist_create(100, sizeof(int));
for (int i = 0; i < 65536; ++i)
{
num = acl_arraylist_append(num, &i);
printf("%d\n", i);
}
}
I'm not going to show the output; the numbers from 1 to 65535 are not exciting.
I distrust void * as the handle type for your array. The user could provide any pointer of their choosing as a handle and there's no way to know that it's the wrong type of pointer. Provide an opaque type instead; in the header, define:
typedef struct acl_arraylist acl_arraylist;
Then have the functions take and return an acl_arraylist *. The client code doesn't need to know what's in it. Your code in array.c might wrap the union arraylist_meta value into a structure:
struct acl_arraylist
{
union arraylist_meta array;
};
You can then play in much the same way you did before. But the user has to work to pass an arbitrary pointer to the functions — sufficiently hard that they won't get it wrong.
The new pointer returned from acl_arraylist_resize is ignored in acl_arraylist_append_ptr.
modified code:
void* acl_arraylist_append_ptr(void *arraylist_void, void **append_element) {
union acl_arraylist_meta *arraylist = arraylist_void;
--arraylist;
if(arraylist->len == arraylist->cap) {
arraylist = acl_arraylist_resize(arraylist, 10);// this line was modified
if(arraylist == NULL) return NULL;
}
*append_element = (char*)(arraylist + 1) + arraylist->sizeof_one_element * arraylist->len;
++arraylist->len;
return arraylist + 1;
}
I'm new in rpcgen and my knowledge in C is not the best. For my project I need to use linked lists because many functions will retrieve a list of data from a database to a client. I have already implemented and generated a code "lista.h" and "lista.c" with the definitions of the functions and the structures of the list and the code of the functions respectively.
In "Linkder.x" (Linkder is the name of my application) I have defined everything necessary to generate the files and included "lista.h".
The problem is when I generate the files with rpcgen applying the command rpcgen -C -a Linkder.x, gives me the following error:
typedef long unsigned int size_t;
^^^^^^^^^^^^^^^^^^^^^
/usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h, line 216: expected '*' or 'identifier'
When I open stddef.h with a text editor, line 216 shows this:
stddef.h
I don't know what is generating this error. I have tested my list creating a test.c file and compiles and runs fine. Maybe this error is caused by the sizeof operator when I use the malloc function to create a new node.
The only thing that fix the error is deleting the #include "lista.h" and every function that use the list in my .x file.
Here is my code:
/*Linkder.x*/
#include "estructuras.h"
#include "lista.h"
program Linkder {
version LINKDER_VER {
/*Funciones*/
tlista *listar_juegos() = 1;
tlista *recomendar_juegos() = 2;
void crear_usuario(struct usuario) = 4;
void juego_fav(struct datos_juego) = 5;
void borrar_juego(struct datos_juego) = 6;
tlista *obtener_usuario_juego(int) = 7;
tlista *obtener_juegos_fav(char[50]) = 8;
void login(struct usuario) = 9;
} = 1;
} = 1;
lista.h:
/*lista.h*/
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo {
char nombre_juego[50];
char nick_jugador[50];
int id_juego;
struct nodo *next;
} tnodo;
typedef struct {
tnodo *head;
int size;
} tlista;
/*funciones*/
//void delete(tlista *l);
int getsize(tlista l);
int isempty(tlista l);
void insert(tlista *l, char c1[50], char c2[50], int num);
/*void view(tlista l);*/
void create(tlista *l);
lista.c:
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "lista.h"
int getsize(tlista l) {
return(l.size);
}
int isempty(tlista l) {
if(l.size == 0) {
return(1);
} else {
return(0);
}
}
void insert(tlista *l, char c1[50], char c2[50], int num) {
tnodo *aux;
if(isempty(*l)) {
l->head = (tnodo*)malloc(sizeof(tnodo));
strcpy(l->head->nombre_juego, c1);
strcpy(l->head->nick_jugador, c2);
l->head->id_juego = num;
l->head->next = NULL;
l->size++;
} else {
aux = l->head;
while(aux->next != NULL)
{
aux = aux->next;
}
aux->next = (tnodo*)malloc(sizeof(tnodo));
strcpy(aux->next->nombre_juego, c1);
strcpy(aux->next->nick_jugador, c2);
aux->next->id_juego = num;
aux->next->next = NULL;
l->size++;
}
}
void create(tlista *l)
{
l->head=NULL;
l->size=0;
}
rpcgen version is 2.27, gcc version is 7.5.0. My OS is Ubuntu 18.04.4 LTS
I have tested my code on different PCs
Thanks in advance.
This answer suggests that unsigned long long isn't defined when you are using rpcgen.
https://stackoverflow.com/a/43186591/10273360
I don't actually know how to evade this error, but I can tell you that the error is coming because you have included the stdio.h and stdlib.h header files, which in turn are including stddef.h inside your own lista.h header file.
#include <stdio.h>
#include <stdlib.h>
And it also happens that you can remove both of these without any problems, as your header file doesn't use any functions coming from these two headers.
The solution to the above problem ends here. But the program still fails compilation for other errors. I'd suggest maybe try solving it yourself, or open another thread for that.
This isn't a like a proper solution or an explanation, but this is what I can tell. More like a pseudo solution. I am not really experienced with rpcgen and it would be great if anyone more experienced can shed some light here.
I am trying to create my own malloc function, and I did not finished yet. Here is related part of my code:
mymalloc.h :
#pragma once
#include <stdlib.h>
typedef struct METADATA{
struct METADATA *next;
struct METADATA *prev;
int free;
size_t size;
}METADATA;
METADATA *metadata;
void *mm_malloc(size_t size);
mymalloc.c
#include "mm_alloc.h"
#include "stdlib.h"
#include "stdio.h"
void *mm_malloc(size_t size) {
if(size == 0)
return NULL;
METADATA *tmp;
long address;
if(metadata == NULL){
sbrk(sizeof(tmp));
sbrk(size);
address = sbrk(0);
return (void *)address;
}
}
In the sbrk(sizeof(tmp)); part of mymalloc.c, I got "Implicit declaration of function sbrk()". What I wanted to do ise creating a place for metadata of new block and also a place for the required size. Where am I doing wrong?
Add the line
#include <unistd.h>
At the top of the file 'mymalloc.c' so that the function is declared
the implementation level of the array-based
#include "stack.h"
void creat_stack(Stack *s) {
s->Top = 0;
}
int isFull(Stack s) {
return (s.Top == Max ? 1 : 0);
}
int isEmpty(Stack s) {
return (s.Top == Max ? 1 : 0);
}
void push(stack_entry e, Stack *s) {
if (!isFull(*s))
s->entry[s->Top++] = e;
else
printf("Error : Stack Overflow\n");
}
void pop(stack_entry *e,Stack *s) {
if(!isEmpty(*s))
*e = s->entry[s->Top--];
else
printf("Error : Stack Underflow\n");
}
the header file stack.h that consists of the prototypes of the functions along with the definition of the stack element type stack_entry.
#pragma once
#include <stdio.h>
#define Max 10
typedef char stack_entry;
typedef struct Stack{
int Top;
stack_entry entry[Max];
}Stack;
void creat_stack(Stack *s);
int isFull(Stack s);
int isEmpty(Stack s);
void push(stack_entry e,Stack *s);
void pop(stack_entry *e, Stack *s);
so my question why i have to include the header file "stack.h" in the "stack.c" file ??
You should have to add the stack.h because this file is it who has all declarations of your typedef define struct and methods
So without then, will be impossible to access any of those informations.
It is the same if you declare a method below the main function and do not declare his signature upstairs the main, you cannot access..
So, all this happens with all include files that you use at the top of your file..
Do not forget C is a sequential language, so you will never know what do you have in the next line if you don't tell the compiler.
check more here
First, don't include "stdio.h" in the header file, you aren't use it there anyway. include it in the source file where you are using it.
You need to include the header file for the "struct stack" and the "define".
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.