Debugging with valgrind and gdb - c

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.

Related

Why when I try to access array of structures it returns random values? (C)

I have a function that returns pointer to array of structures. However, when I try to access any of the values of returned structure, it prints random symbols.
#include <stdio.h>
struct MY {
int i;
char string[30];
};
struct MY* myFunc() {
struct MY arrayOfStructs[3];
struct MY tempStruct;
struct MY* arrayOfStructsPtr = arrayOfStructs;
tempStruct.i = 1;
tempStruct.string[0] = 'H';
tempStruct.string[1] = 'i';
arrayOfStructs[0] = tempStruct;
tempStruct.i = 2;
tempStruct.string[0] = 'L';
tempStruct.string[1] = 'o';
arrayOfStructs[1] = tempStruct;
tempStruct.i = 3;
tempStruct.string[0] = 'M';
tempStruct.string[1] = 'Y';
arrayOfStructs[2] = tempStruct;
return arrayOfStructsPtr;
}
int main()
{
struct MY* arrayOfStructs = myFunc();
for(int i = 0; i < 3; i++) printf("%d\n", arrayOfStructs[i].i);
return 0;
}
You return a reference to the local array which stops to exist when function returns. It is Undefined Behaviour.
You need:
struct MY* myFunc(void) {
static struct MY arrayOfStructs[3];
or
struct MY* myFunc(void) {
struct MY *arrayOfStructs = malloc(3 * sizeof(*arrayOfStructs));
or pass the buffer allocated by the caller.
struct MY *myFunc(struct MY *arrayOfStructs) {
/* .... */
If you dynamically allocate memory you should free it after use
You return a pointer to a local variable which is out of scope when the function returns. Some alternatives:
The caller main() allocates variable and pass it to myFunc() for initialization.
#include <stdio.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
void myFunc(struct MY arrayOfStructs[N]) {
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < N; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
}
int main() {
struct MY arrayOfStructs[N];
myFunc(arrayOfStructs);
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
}
As used here you don't really need to store i as it's just index of the struct + 1.
myFunc() dynamically allocate the variables with malloc() and return the pointer. Caller is responsible for free'ing the allocated memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3
struct MY {
int i;
char string[30];
};
struct MY *myFunc() {
struct MY *arrayOfStructs = malloc(N * sizeof *arrayOfStructs);
if(!arrayOfStructs) return NULL; // malloc failed
char *strings[N] = { "Hi", "Lo", "MY" };
for(size_t i = 0; i < sizeof strings / sizeof *strings; i++) {
arrayOfStructs[i].i = i + 1;
strcpy(arrayOfStructs[i].string, strings[i]);
}
return arrayOfStructs;
}
int main() {
struct MY *arrayOfStructs = myFunc();
if(!arrayOfStructs) return 1;
for(int i = 0; i < N; i++)
printf("%d\n", arrayOfStructs[i].i);
free(arrayOfStructs);
}
myFunc(): make variables static (not recommended).

Unable to free an integer array in a struct

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.

Expected identifier or '(' parse issue in C language in Xcode

I was working on pop and push methods on the stack. Actually in this code I am creating dynamic array using pointers and malloc function. Then I was trying to add or delete elements to dynamic array with pop and push methods.But I getting the error in the question. I can't see any error in the code. Can you help me?
Here my main.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
stack * init(){
stack *s = (stack *) malloc(sizeof(stack));
s->items = NULL;
s->top = 0;
s->count = 2;
return s;
}
int pop(stack *s){
if(s->items == NULL){
printf("Items is empty.\n");
return -1;
}
if(s->top<=s->count/4){
int *items2 = (int *)malloc(sizeof(int)*s->count/2);
for (int i = 0; i < (s->count/2); i++){
items2[i] = s->items[i];
}
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count /= 2;
}
return s->items[--s->top];
}
void push(int a, stack *s){
if(s->items == NULL){
s->items = (int *)malloc(sizeof(int) * 2);
}
if(s->top>=s->count){
int *items2 = (int *)malloc(sizeof(int)*s->count*2);
for (int i = 0; i < s->count; i++)
items2[i] = s->items[i];
free(s->items); // burada "dizi" adındaki dizimiz dizi2 ile aynı yeri gösterdiğinde önceki 2 elemanlık dizi lost in space olacak bunu önlemek için free(dizi) diyerek o 2 elemanı bellekten siliyoruz.
s->items = items2;
s->count *= 2;
}
s->items[s->top++] = a;
}
void getItems(stack *s){
printf("count: %d\n", s->count);
for (int i = 0; i < s->top; i++) {
printf("%d\n", s->items[i]);
}
}
main_header.h file
#ifndef main
#define main
struct s {
int count;
int top;
int *items;
};
typedef struct s stack;
stack * init(void);
int pop(stack *);
void getItems(stack *);
void push(int, stack *);
#endif
test_stack.c file
#include <stdio.h>
#include <stdlib.h>
#include "main_header.h"
int main(){
stack *s1 = init();
stack *s2 = init();
for (int i = 0; i < 10; i++) {
push(i*10, s1);
}
getItems(s1);
for (int i = 0; i < 10; i++) {
push(pop(s1), s2);
}
return 0;
}
After #define main in “main_header.h”, the code int main(){ in “test_stack.c” is replaced by int (){. This causes the syntax error that the compiler (not Xcode) reports.
Do not use main in “main_header.h” as an indicator for whether the header file has been included already. Use some other name that you will not use for anything else, such as main_h or main_header_h.
(Clang is the compiler. Xcode is the overall integrated development environment that facilitates use of the compiler, organizes your projects files, opens editors, maintains your project options, and so on.)

Why does calling a function modify the value of an array of pointer to function that weren't given in parameter?

I've got a struct that contains a pointer to function and an array of pointers to function. I'm passing the first pointer (not the array) as parameter of a function which is supposed to tell me whether an array of integers is sorted or not (it can be in ascending or descending order and this is defined by compFct, which is the pointer to function given in parameter).
Unfortunately that function is changing the values in the array of pointers in my struct (without changing the value of my pointer to function given in parameter).
Using gdb I managed to know when were made the changes in my array. It appears to be modified after the first printf in the printSorted function.
My typedef :
typedef int (*PtrCompFct)(int, int);
typedef int (*PtrSortFct)(int*, int, int, PtrCompFct);
The struct :
typedef struct
{
int nbFct;
PtrCompFct compFct;
PtrSortFct *sortFct;
} SortCompFct_s;
Here is how I'm calling my function (userChoices is of SortCompFct_s type):
printSorted(myArr, myArrSize, userChoices->compFct);
And the fonction that is changing my structure :
int printSorted(int *arr, int arrSize, PtrCompFct compFct)
{
for (int i=0; i<(arrSize-1); i++)
{
if (compFct(arr[i+1], arr[i]))
{
//this is when my array of pointers to function is modified
printf("The array isn't sorted\n\n");
return 0;
}
}
printf("The array is sorted\n\n");
return 1;
}
With gdb before the printf I have :
(gdb) print main::userChoices->sortFct[0]
$36 = (PtrSortFct) 0x5555555548ea <quickSort>
and after :
(gdb) print main::userChoices->sortFct[0]
$37 = (PtrSortFct) 0x7fffffffddc0
As you can see the pointer to my quickSort function has been modified.
EDIT : include of the simplified and verifiable code, the thing is that this code is working properly, even with the printSorted function
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef int (*PtrCompFct)(int, int);
typedef int (*PtrSortFct)(int*, int, int, PtrCompFct);
typedef struct
{
int nbFct;
PtrCompFct compFct;
PtrSortFct *sortFct;
} SortCompFct_s;
typedef SortCompFct_s *PtrSortCompFct_s;
void initTab(int *arr, int arrSize)
{
time_t t;
srand(time(&t));
for (int i=0; i<arrSize; i++)
{
arr[i] = rand();
}
}
int ascendingSort(int elmt1, int elmt2)
{
return (elmt1 < elmt2);
}
int descendingSort(int elmt1, int elmt2)
{
return (elmt1 > elmt2);
}
void switche(int *arr, int ind1, int ind2)
{
int temp = arr[ind1];
arr[ind1] = arr[ind2];
arr[ind2] = temp;
}
int bubbleSort(int *arr, int ind1, int ind2, PtrCompFct fctComp)
{
int sorted;
for (int i=ind1; i<ind2; i++)
{
sorted = 1;
for (int j=0; j<ind2; j++)
{
if (fctComp(arr[j+1], arr[j]))
{
switche(arr, j, j+1);
sorted = 0;
}
}
if (sorted) return 0;
}
return 0;
}
void printArr(int *arr, int arrSize)
{
for (int i=0; i<arrSize; i++)
{
printf("%16d\n", arr[i]);
}
}
int printSorted(int *arr, int arrSize, PtrCompFct compFct)
{
for (int i=0; i<arrSize-1; i++)
{
if (compFct(arr[i+1], arr[i]))
{
//this is when my array of pointers to function is modified
printf("The array isn't sorted\n\n");
return 0;
}
}
printf("The array is sorted\n\n");
return 1;
}
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(3*sizeof(int))) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = arrSortFct;
}
return userChoices;
}
int main(void)
{
int arrSize = 10;
int arr[arrSize];
initTab(arr, arrSize);
PtrSortCompFct_s userChoices;
if ((userChoices = malloc(3*sizeof(int))) != NULL) userChoices = menu();
printArr(arr, arrSize);
printSorted(arr, arrSize, userChoices->compFct);
userChoices->sortFct[0](arr, 0, arrSize-1, userChoices->compFct);
printArr(arr, arrSize);
printSorted(arr, arrSize, userChoices->compFct);
return 0;
}
With gdb before the printf I have: ... and after:
The root cause of your problem is in how you have initialized userChoices->sortFct (you have not shown the code which performs this initialization).
That array is pointing to dangling heap or stack memory, and a call to printf overwrites that memory.
if ((userChoices = malloc(6*sizeof(int))) != NULL) userChoices = menu();
That code is completely bogus: heap-allocating memory for userChoices and then immediately overwriting userChoices with return value from menu() only serves to leak memory. As mentioned in the comments, 6*sizeof(int) is also completely bogus size.
I would guess that your menu() looks something like this:
struct SortCompFct_s* menu()
{
struct SortCompFct_s ret;
ret.compFct = &SomeFunc;
ret.sortFct = malloc(...);
ret.sortFct[0] = &quickSort;
return &ret; // Oops: returning address of a local!
}
If that is in fact what you did, dangling stack is exactly your problem. You should turn on maximum compiler warnings (-Wall -Wextra if using GCC), so the compiler tells you you are doing something wrong.
Update:
My guess was close:
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(3*sizeof(int))) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = arrSortFct;
}
return userChoices;
}
The problem is that userChoices->sortFct points to a local (stack) variable arrSortFct. That local variable becomes invalid after return from menu, and at that point userChoices->sortFct is pointing to dangling stack (as I guessed).
Here is correct way to write this function (omitting error checking of malloc return for clarity):
PtrSortCompFct_s menu(void)
{
PtrSortCompFct_s userChoices;
PtrSortFct arrSortFct[] = {bubbleSort};
if ((userChoices = malloc(sizeof(*userChoices)) != NULL)
{
userChoices->nbFct = 1;
userChoices->compFct = ascendingSort;
userChoices->sortFct = malloc(sizeof(arrSortFct));
memcpy(userChoices->sortFct, arrSortFct, sizeof(arrSortFct));
}
return userChoices;
}
You should also need to fix your main like so:
PtrSortCompFct_s userChoices;
PtrSortCompFct_s userChoices = menu();
... use userChoices ...
free(userChoices->sortFct);
free(sortFct);
return 0;

Function Accepting Struct pointer and returning struct pointer has wierd behaviour?

I my code i call the insert function and it passes a pointer to the struct (table) and the insert function recieves a pointer and does some stuff and returns it again. But running the code gives segmentation fault. when i try to access the values in the struct array using the pointer passed.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define __USE_BSD
#include <string.h>
#include "speller.h"
#include "dict.h"
typedef struct
{ // hash-table entry
Key_Type element; // only data is the key itself
enum {empty, in_use, deleted} state;
} cell;
typedef unsigned int Table_size; // type for size-of or index-into hash table
struct table
{
cell *cells; Table_size table_size; // cell cells [table_size];
Table_size num_entries; // number of cells in_use
// add anything else that you need
};
int hashfunc(Key_Type k, Table_size size)
{
printf("enterd\n");
char * d = k;
int hash = 0;
int c;
printf("%s\n", d);
printf("wtf??\n");
while (c = *d++)
{
printf("maybehere??\n");
hash = hash + c;
}
hash = hash%size;
printf("%d\n", hash);
return hash;
}
Table initialize_table (Table_size size)
{
Table t = malloc(sizeof(struct table));
t->table_size = size;
cell hash_table[size];
for (int i=0; i<size; i++)
{
hash_table[i].state = empty;
hash_table[i].element = "-";
//printf("initialised\n");
}
t->num_entries = 0;
t->cells = hash_table;
/*for (int i = 0; i < t->table_size; i++)
{
printf("%d %s\n", i, (t->cells + i)->element);
}*/
return t;
}
int a = 0;
Table insert (Key_Type k, Table t)
{
//printf("insert called %d\n", a);
printf("%d\n", t->table_size);
//printf("%s\n", (t->cells + 2)->element);
// as soon as program reaches here i get output like - 1 (NULL)
2 (NULL) and then segmentation fault
for (int i = 0; i < t->table_size; i++)
{
printf("%d %s\n", i, (t->cells + i)->element);
}
a++;
printf("%s\n", k);
int hash_code = hashfunc(k, t->table_size);
// Linear Probing
printf("im here\n");
while(strcmp((t->cells + hash_code)->element,"-") != 0)
{
if (strcmp((t->cells + hash_code)->element,k) == 0)
{
printf("return at if\n");
return t;
}
else if (hash_code == (t->table_size - 1))
hash_code = 0;
else
hash_code++;
}
(t->cells + hash_code)->element = k;
(t->cells + hash_code)->state = in_use;
t->num_entries += 1;
printf("return at end with value %s\n", k);
printf("inserted value %s\n", (t->cells + hash_code)->element);
return t;
}
Boolean find (Key_Type k, Table t)
{
return FALSE;
}
void print_table (Table t)
{
Table_size size = t->table_size;
for (int i = 0; i<size; i++)
{
if (strcmp((t->cells + i)->element,"-") != 0)
printf("%d %s\n", i, (t->cells + i)->element);
}
}
void print_stats (Table t)
{
}
void main()
{
Table table;
Table_size table_size = 19;
int a = 5;
Key_Type input[5] = {"a","b","ab","abc","abcd"};
table= initialize_table (table_size);
//printf("%s\n", input[1]);
while (a)
{
table= insert("a",table);
a--;
}
printf("printing table\n");
print_table(table);
}
this is the dict.h code
typedef char* Key_Type;
typedef struct table* Table; // allows different definitions of struct table
Table initialize_table (); // allows different parameters
Table insert (Key_Type, Table);
Boolean find (Key_Type, Table);
void print_table (Table);
void print_stats (Table);
This is the speller.h code
typedef enum {FALSE, TRUE} Boolean;
extern int verbose; // used to control monitoring output
extern int mode; // used to control your algorithm
extern char *prog_name; // used by check
void check (void *memory) ; // check result from strdup, malloc etc.
I believe i dont understand how the pointers work in this program.
Here is the problem,
cell hash_table[size];
and then, you make t->cells point to hash_table but hash_table is a local variable in the initialize_table() function, so it's destroyed/deallocated when the function returns and no longer accessible after it returns.
You should allocate it on the heap too, like this
cell *hash_table;
hash_table = malloc(size * sizeof(*hash_table));
if (hash_table == NULL)
return NULL; // Probably free `t' so that no memory leaks
// happen
Accessing such a local variable that was allocated in the stack frame of a function, after that function returns is undefined behavior, the problem could happen somewhere else in the code or when accessing the pointer pointing to the deallocated data.
A side note
Be consistent with naming, and unambigous, you used a weird CamelCase and underscore combination, it doesn't matter if it's weird or not, keep it and preserve it throughout the code — respect your own style. And call the cell typedef: Cell instead.
Also, always check the return value of malloc() which returns NULL on error (allocation failure), you should write code as if all the bad things will happen, because they do.
And finally, never typedef a pointer. It doesn't help whatsoever, it only obscures the fact that a declaration is that of a pointer.

Resources