Pointer losing value in C - c

I have a struct which has a char * to act as it's name for finding it. I also have an array of struct declared. I am trying to assign a struct a name, but the problem I am having is the char * is continuing to change values to whatever the last name is set. This is wrecking havoc for the logic of my code. I have tried using malloc(), but that did not change the results.
code:
struct foo {
char* label;
}
typedef struct foo fum;
fum foolist[25];
/*initialize all elements in foo list to be "empty"*/
bool setArray(char* X) {
for(int i =0; i <25;i++) {
if(strncmp("empty", foolist[i].label,5*sizeof(char))==0) {
//tried char* temp = (char*)malloc(32*sizeof(char));
//foolist[i].label = temp; no change.
foolist[i].label = X;
return true;
}
}
return false;
}
I want label to not change with 'X' once the declaration is made, i have tried using malloc(), probably not correctly though.

You can do either:
foolist[i].label = malloc(strlen(X) + 1);
if ( !foolist[i].label ) {
perror("couldn't allocate memory"):
exit(EXIT_FAILURE);
}
strcpy(foolist[i].label, X);
or, if you have strdup() available:
foolist[i].label = strdup(X);
if ( !foolist[i].label ) {
perror("couldn't allocate memory"):
exit(EXIT_FAILURE);
}

Related

Error using memcpy : "Access violation reading location 0x0000000000000000"

I am trying to write something similar to std::vector but in c to store a bunch of mathematical vectors.
Here is the line that is casing the error.
pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));
My Intention: Copy data from pVl->pData to pNewData. Then assign the return value, which is the
pointer to start of the newly copied data memory and assign it to pVl->pData. I am not sure what I am doing wrong.
MRE:
#include <stdlib.h>
#include <string.h>
typedef enum R_Code { R_OK, R_WARNING, R_FAIL, R_FATAL } R_Code;
struct Vector2_s
{
float x;
float y;
} const Default_Vector2 = { 0.0f, 0.0f };
typedef struct Vector2_s Vector2;
struct Vector2List_s
{
//current capacity of the List
size_t capacity;
//current size of the list
size_t size;
//data buffer
Vector2* pData;
} const Default_Vector2List = { 0, 0, NULL };
typedef struct Vector2List_s Vector2List;
R_Code Vector2List_ReAllocateMem(Vector2List* pVl) {
if (pVl->capacity == 0) {
pVl->capacity++;
}
Vector2* pNewData = malloc(pVl->capacity * 2 * sizeof(Vector2));
if (pNewData == NULL) {
return R_FAIL;
}
pVl->capacity *= 2;
pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));//EXPECTION THROWN IN THIS LINE
free(pNewData);
return R_OK;
}
R_Code Vector2List_PushBack(Vector2List* pVl, const Vector2 v) {
if (pVl->size == pVl->capacity) {
R_Code rcode = Vector2List_ReAllocateMem(pVl);
if (rcode == R_FAIL) {
return rcode;
}
}
pVl->pData[pVl->size] = v;
pVl->size++;
return R_OK;
}
int main() {
Vector2List vl = Default_Vector2List;
Vector2List_PushBack(&vl, Default_Vector2);
return 0;
}
Within the function Vector2List_ReAllocateMem you allocated dynamically memory
Vector2* pNewData = malloc(pVl->capacity * 2 * sizeof(Vector2));
then in this statement
pVl->pData = memcpy(pNewData, pVl->pData, sizeof(pVl->pData));
you are using the null pointer pVl->pData as a source of data that invokes undefined behavior.
Moreover you freed the allocated memory.
free(pNewData);
Also using this expression sizeof(pVl->pData) does not make a sense.
It seems what you need is the following
pVl->pData = pNewData;
Though if you are going to reallocate memory then instead of malloc you need to use realloc.
You need to rewrite the function entirely.

Pass local variable of a function back to it's parameter

I'm wanting to pass a local variable within a function, back through it's pointer parameter (not returned).
My assignment uses a stack data structure, and one criteria that must be used is the Pop() function must have a pointer parameter that is used to return the top-most item on the stack. I have used this before. My program became more complex with a data struct, I started getting either segmentation faults, or the data not being saved after the function's frame popped.
// Definitions
typedef char * string;
typedef enum { SUCCESS, FAIL } result;
typedef enum { INTEGER, DOUBLE, STRING } item_tag;
// Result Check
static result RESULT;
// Item_Tag
typedef struct {
item_tag tag;
union {
int i;
double d;
string s;
} value;
} item;
// Declarations
int STACK_SIZE = 0;
const int MAX_STACK_SIZE = 1024; // Maximum stack size
item stack[1024];
// Pop
result Pop(item *ip){
item poppedItem;
item * pointerReturn = malloc(sizeof(item));
// Check stack size is not 0
if(STACK_SIZE == 0){
return FAIL;
}
// If stack size is only 1, creates a blank stack
else if(STACK_SIZE == 1){
item emptyItem;
// Initialize
emptyItem.tag = INTEGER;
emptyItem.value.i = 0;
// Check top item's tag
poppedItem = stack[0];
// Store top item data based on tag
switch(stack[0].tag){
case STRING:
poppedItem.value.s = stack[0].value.s;
case DOUBLE:
poppedItem.value.d = stack[0].value.d;
default:
poppedItem.value.i = stack[0].value.i;
}
poppedItem.tag = stack[0].tag;
// Allocate memory for parameter, and have it point to poppedItem
ip = malloc(sizeof(poppedItem));
*ip = poppedItem;
// Store empty stack to top of stack
stack[0] = emptyItem;
// Decrease stack size
STACK_SIZE--;
}
// Grab top Item from stack
else{
// Check top item's tag
poppedItem = stack[0];
// Store top item data based on tag
switch(stack[0].tag){
case STRING:
poppedItem.value.s = stack[0].value.s;
case DOUBLE:
poppedItem.value.d = stack[0].value.d;
default:
poppedItem.value.i = stack[0].value.i;
}
poppedItem.tag = stack[0].tag;
// Allocate memory for parameter, and have it point to poppedItem
ip = malloc(sizeof(poppedItem));
*ip = poppedItem;
// Reshuffle Items in Stack
for(int idx = 0; idx < STACK_SIZE; idx++){
stack[idx] = stack[idx + 1];
}
STACK_SIZE--;
}
return SUCCESS;
}
My knowledge with pointers is alright, and memory location/management. But I can't claim to be an expert by any means. I don't exactly know what happens in the background when you're using the function's own pointer parameter as a means of passing data back.
What is the correct syntax to solve this problem?
How can a parameter pass something back?
Thanks in advance!
EDIT*
Since many people are confused. I'll post some snippets. This is an assignment, so I cannot simply post all of it online as that'd be inappropriate. But I think it's okay to post the function itself and have people analyze it. I'm aware it's a bit messy atm since I've edited it several dozen times to try and figure out the solution. Sorry for the confusion. Keep in mind that not all the code is there. just the function in question, and some of the structure.
The function should receive a pointer to a valid object:
item catcher;
myFunc(&catcher); // Pass a pointer to catcher
and the function should modify the object it received a pointer to:
void myFunc(item *itemPointer)
{
itemPointer->variable = stuff;
// or
*itemPointer = someItem;
}
Update:
You're overcomplicating things immensely – there should be no mallocs when popping, and you're leaking memory all over the place.
(Your knowledge of pointers and memory management is far from "alright". It looks more like a novice's guesswork than knowledge.)
It should be something more like this:
result Pop(item *ip){
if (STACK_SIZE == 0){
return FAIL;
}
else {
*ip = stack[0];
for(int idx = 0; idx < STACK_SIZE; idx++){
stack[idx] = stack[idx + 1];
}
STACK_SIZE--;
}
return SUCCESS;
}
but it's better to push/pop at the far end of the array:
result Pop(item *ip){
if (STACK_SIZE == 0){
return FAIL;
}
else {
*ip = stack[STACK_SIZE-1];
STACK_SIZE--;
}
return SUCCESS;
}
Response to the originally posted code:
typedef struct{
variables
}item;
void myFunc(item *itemPointer){
item newItem;
newItem.variable = stuff;
}
int main(){
item * catcher;
myFunc(catcher);
printf("%s\n", catcher.variable);
}
A few issues.
Your program will not compile. variable has to have a type.
void myFunc(item *itemPointer){
item newItem;
newItem.variable = stuff;
}
stuff is not defined; item *itemPointer is not used.
item * catcher pointer has to point to allocated memory. It is not initialized.
Pass arguments via pointers and modify member of the structure like this:
void myFunc(item *itemPointer, const char *string){
itemPointer->variable = string ;
}
Solution like:
void myFunc(item *itemPointer)
{
itemPointer->variable = stuff;
// or
*itemPointer = someItem;
}
is possible, but it assumes that stuff or someItem is a global variable which is not the best programming practice IMO.
Retrieve value from pointer via -> not . operator.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char * variable;
}item;
void myFunc(item *itemPointer, const char *string){
itemPointer->variable = string ;
}
int main(){
item * catcher;
char *new_string = "new string";
catcher = malloc(sizeof(item));
myFunc(catcher, new_string);
printf("%s\n", catcher->variable);
free(catcher);
return 0;
}
OUTPUT:
new string

Returning an array of structs from a recursive huffman tree C

i have a task in class to the return an array of struck Symbol from huffman tree.
the function getSL get a huffman tree(only) and return struck of Symbol.
each spot in the array contain a char from the "leaf" of the tree and the
length of his code(how many cross section till the leaf).
my main problem was to find how i advance the cnt of the arry that it will not overright the arry.
thank you.
typedef struct HNode {
char chr;
struct HNode *left, *right;
} HNode;
typedef struct {
char chr;
int counter;
}Symbol;
this is what i did till now.
Symbol * getSL(HNode *root) {
if (root->left == NULL && root->right == NULL) {
Symbol* b = (Symbol*)malloc(100);
b->counter=0;
b->chr = root->chr;
return b;
}
Symbol* a = (Symbol*)malloc(100);
if (root->left != NULL) {
a= getSL(root->left);
a->counter++;
}
if (root->right != NULL) {
a= getSL(root->right);
a->counter++;
}
return a;
}
Apart from the malloc problem (see the comments already), you have a fundamental problem: You allocate a new struct, but then replace it with the one returned from the recursive call. So you lose the one created before (actually, memory leaking!).
Easiest variant would now be converting your Symbol to linked list nodes; then you simply could do:
Symbol* lastLeafFound; // probaly a function parameter!
if(!(root->left || root->right))
{
// leaf found:
Symbol* a = (Symbol*)malloc(sizeof(Symbol));
a->chr = root->chr;
a->counter = /* ... */;
a->next = NULL;
lastLeafFound->next = a;
// you might return a now as last leaf found, using it in the next recursive call
}
Sure, above code is incomplete, but should give you the idea...
If you cannot modify your struct, then you need to create an array and pass it on to every new recursive call (prefer not to use global variables instead):
void doGetSL
(
HNode* root,
Symbol** symbols, // your array to be used
unsigned int* count, // number of symbols contained so far
unsigned int* capacity // maximum possible symbols
)
Passing all data as pointers allows the function to modify them as needed and they are still available from outside...
Symbol* getSL(HNode* root)
{
if(!root)
return NULL;
unsigned int count = 0;
unsigned int capacity = 128;
// allocate a whole array:
Symbol* array = malloc(capacity*sizeof(Symbol));
if(array) // malloc could fail...
{
doGetSL(root, &array, &count, &capacity);
// as you cannot return the number of leaves together with
// the array itself, you will need a sentinel:
array[count].chr = 0;
// obvious enough, I'd say, alternatively you could
// set counter to 0 or -1 (or set both chr and counter)
}
return array;
}
doGetSL will now use above set up "infrastructure":
{
if(!(root->left || root->right))
{
if(*count == *capacity)
{
// no memory left -> we need a larger array!
// store in separate variables:
unsigned int c = *capacity * 2;
Symbol* s = realloc(symbols, c * sizeof(Symbol));
// now we can check, if reallocation was successful
// (on failure, s will be NULL!!!):
if(s)
{
// OK, we can use them...
*symbols = s; // <- need a pointer for (pointer to pointer)!
*capacity = c;
}
else
{
// re-allocation failed!
// -> need appropriate error handling!
}
}
(*symbols)[count].chr = root->chr;
(*symbols)[count].counter = /*...*/;
++*count;
}
else
{
if(root->left)
{
doGetSL(root->left, symbols, count, capacity);
}
if(root->right)
{
doGetSL(root->right, symbols, count, capacity);
}
}
}
One thing yet omitted: setting the counter. That would be quite easy: add another parameter to doGetSL indicating the current depth, which you increment right when entering doGetSL, you can then just assign this value when needed.
You can further improve above variant (especially readability), if you introduce a new struct:
struct SLData
{
Symbol* symbols, // your array to be used
unsigned int count, // number of symbols contained so far
unsigned int capacity // maximum possible symbols
};
and pass this one instead of the three pointers:
doGetSL(HNode*, struct SLData*, unsigned int depth);
struct SLData data =
{
.count = 0;
.capacity = 128;
.array = malloc(capacity*sizeof(Symbol));
};
if(data.array)
doGetSL(root, &data, 0); // again passed as pointer!

Finding words in tree by prefix

In my binary search tree I want to create a function that can get all words starting with a prefix and store all words in an array called results
this is my tree
struct BinarySearchTree_t
{
char *mot,*def;
struct BinarySearchTree_t *left;
struct BinarySearchTree_t *right;
};
typedef struct BinarySearchTree_t BinarySearchTree;
my function :
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, char*** results)
{
BinarySearchTree *tmp;
tmp=tree;
static int size=0;
if (!tmp)
return 0;
else if (strncmp(tmp->mot,prefix,strlen(prefix))==0)
{
(*results)= realloc(*results,(1+size)*sizeof(*(*results)));
(*(*results+size))= malloc(strlen(tmp->mot)*sizeof(char));
strcpy((*results)[size],tmp->mot);
size++;
return (1 + findWordsByPrefix(tmp->left,prefix, &results) + findWordsByPrefix(tmp->right,prefix, &results));
}
else
return (strncmp(tmp->mot,prefix,strlen(prefix))<0)?findWordsByPrefix(tmp->right,prefix, &results):findWordsByPrefix(tmp->left,prefix, &results) ;
}
This function should return a number of words starting with the given prefix.
my problem is that the program crash when it is run , and I don't how to resize my array results
so every time I found a word I should increase the size of the results array .
and I would know how exacly manipulate the pointer of pointer of pointer given in arg of this function (char ***results) : what exactly means?
If I simply compile your code, I get severe compiler warnings including:
1>binarysearchtree.c(98) : warning C4047: 'function' : 'char ***' differs in levels of indirection from 'char ****'
1>binarysearchtree.c(98) : warning C4024: 'findWordsByPrefix' : different types for formal and actual parameter 3
This alone will cause a crash -- you are calling your own function recursively with the wrong arguments.
Next, I believe you need to allocate one more than the length of the string, to hold a copy of a string:
malloc((strlen(tmp->mot) + 1 )*sizeof(char))
Next, you're passing around an array of strings of variable size -- and storing the size in a static variable. It's impossible to know if this will work, so don't do it.
Instead, if you want to use a dynamic array of strings, I suggest extracting out a struct to hold them, like so:
struct ResultTable_t
{
int size;
char **results;
};
typedef struct ResultTable_t ResultTable;
void InitializeResults(ResultTable *p_table)
{
p_table->size = 0;
p_table->results = NULL;
}
void AddResult(ResultTable *p_table, char *result)
{
if (result == NULL)
return;
p_table->size++;
p_table->results = realloc(p_table->results, p_table->size * sizeof(*p_table->results));
p_table->results[p_table->size-1] = malloc((strlen(result) + 1) * sizeof(**p_table->results));
strcpy(p_table->results[p_table->size-1], result);
}
void FreeResults(ResultTable *p_table)
{
if (p_table->results != NULL)
{
int i;
for (i = 0; i < p_table->size; i++)
{
free(p_table->results[i]);
}
free(p_table->results);
}
p_table->size = 0;
p_table->results = NULL;
}
(As an improvement, you might consider using geometric growth instead of linear growth for your table of results.)
Then your function becomes:
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, ResultTable *p_table)
{
if (!tree)
return 0;
else if (strncmp(tree->mot,prefix,strlen(prefix))==0)
{
AddResult(p_table, tree->mot);
return (1 + findWordsByPrefix(tree->left,prefix, p_table) + findWordsByPrefix(tree->right,prefix, p_table));
}
else if (strncmp(tree->mot,prefix,strlen(prefix))<0)
{
return findWordsByPrefix(tree->right,prefix, p_table);
}
else
{
return findWordsByPrefix(tree->left,prefix, p_table);
}
}
And you would use it like:
ResultTable results;
InitializeResults(&results);
// Get some prefix to search for.
char prefix = GetSomePrefix();
int size = findWordsByPrefix(tree, prefix, &results);
// Do something with the results
// Free all memory of the results
FreeResults(&results);
Update
If the ResultTable is distasteful for some reason, you can pass the dynamic array and array sizes in directly:
void AddResult(char ***p_results, int *p_size, char *word)
{
if (word == NULL)
return;
(*p_size)++;
(*p_results) = realloc(*p_results, ((*p_size)+1) * sizeof(**p_results));
(*p_results)[(*p_size)-1] = malloc((strlen(word) + 1) * sizeof(***p_results));
strcpy((*p_results)[(*p_size)-1], word);
}
void FreeResults(char ***p_results, int *p_size)
{
int i;
if (p_results == NULL || *p_results == NULL)
return;
for (i = 0; i < (*p_size); i++)
{
free ((*p_results)[i]);
}
free (*p_results);
*p_results = NULL;
*p_size = 0;
}
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, char ***p_results, int *p_size)
{
if (!tree)
return 0;
else if (strncmp(tree->mot,prefix,strlen(prefix))==0)
{
AddResult(p_results, p_size, tree->mot);
return (1 + findWordsByPrefix(tree->left,prefix, p_results, p_size) + findWordsByPrefix(tree->right,prefix, p_results, p_size));
}
else if (strncmp(tree->mot,prefix,strlen(prefix))<0)
{
return findWordsByPrefix(tree->right,prefix, p_results, p_size);
}
else
{
return findWordsByPrefix(tree->left,prefix, p_results, p_size);
}
}
and use like:
char **results = NULL;
int tablesize = 0;
// Get some prefix to search for.
char prefix = GetSomePrefix();
int size = findWordsByPrefix(tree, prefix, &results, &tablesize);
// Do something with the results
// Free all memory of the results
FreeResults(&results, &tablesize);

C Pointer and Memory Allocation: Realloc Arrays and Pointer Passing

For those experienced with C, this will be a simple memory allocation/referencing problem:
Here are my data structures:
struct configsection {
char *name;
unsigned int numopts;
configoption *options;
};
typedef struct configsection configsection;
struct configfile {
unsigned int numsections;
configsection *sections;
};
typedef struct configfile configfile;
Here are my routines for initializing a configsection or configfile, and for adding a configsection to a configfile:
// Initialize a configfile structure (0 sections)
void init_file(configfile *cf) {
cf = malloc(sizeof(configfile));
cf->numsections = 0;
}
// Initialize a configsection structure with a name (and 0 options)
void init_sec(configsection *sec, char *name) {
sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
}
// Add a section to a configfile
void add_sec(configfile *cf, configsection *sec) {
// Increase the size indicator by 1
cf->numsections = cf->numsections + 1;
// Reallocate the array to accommodate one more item
cf->sections = realloc(cf->sections, sizeof(configsection)*cf->numsections);
// Insert the new item
cf->sections[cf->numsections] = *sec;
}
I believe my problem originates in my init_sec() function. Here is an example:
int main(void) {
// Initialize test configfile
configfile *cf;
init_file(cf);
// Initialize test configsections
configsection *testcs1;
init_sec(testcs1, "Test Section 1");
// Try printing the value that should have just been stored
printf("test name = %s\n", testcs1->name);
Although the printf() in init_sec() successfully prints the name I just stored in the configsection, attempting the same thing in the printf() of main() produces a segmentation fault. Further, addsec() produces a segmentation fault.
This routine should be
void init_file(configfile **cf) {
*cf = malloc(sizeof(configfile));
(*cf)->numsections = 0;
(*cf)->sections = NULL; // You forgot to initialise this.
}
i.e. called by init_file(&myconfigfilepointer); so the malloc return value gets passed back.
Need to do the same trick for init_sec
This function is incorrect - here is a corrected version
void add_sec(configfile *cf, configsection *sec) {
// Increase the size indicator by 1
// Reallocate the array to accommodate one more item
cf->sections = realloc(cf->sections, sizeof(configsection)*(1 + cf->numsections));
// Insert the new item
cf->sections[cf->numsections] = *sec; // Since arrays start at 0
cf->numsections = cf->numsections + 1;
}
You then need to adjust the calls in main
At no point do you initialise cf->sections, which means when you try to realloc it the first time, you're passing rubbish. Adding:
cf->sections = NULL;
to init_file should help.
You're also not checking any return codes, but you knew that yes?
You need to pass a pointer of the value to be updated... eg:
// Initialize a configfile structure (0 sections)
void init_file(configfile **cf) {
*cf = malloc(sizeof(configfile));
(*cf)->numsections = 0;
}
configfile *var;
init_file(&var);
printf("%d\n", var->numsections);
Otherwise you are just updating the local pointer *cf and not the original passed in value
You need to really rethink how function arguments are passed in C and what pointers are. Your problem has nothing to do with memory allocation. Rather, your code is assigning a pointer to dynamically allocated memory only to a local variable, of which the calling code knows nothing.
While you could solve the problem by passing a pointer to the caller's pointer (i.e. a double pointer), this is not necessarily the most elegant or most usual way of handling things. Rather, you should return the result of the allocation from the function. While you're at it, you should also use calloc to zero out the memory right away. Wrapping it all up:
typedef struct substuff_
{
int a;
double b;
} substuff;
typedef struct stuff_
{
unsigned int n;
substuff * data;
} stuff;
substuff * init_substuff()
{
substuff * const p = malloc(sizeof *p);
if (p) { p->a = 5; p->b = -0.5; }
return p;
}
stuff * init_stuff()
{
substuff * const p = init_substuff();
if (!p) return NULL;
stuff * const q = malloc(sizeof *q);
if (q) { q->n = 10; q->data = p; }
return q;
}
As an exercise, you should write the corresponding functions void free_substuff(substuff *) and void free_stuff(stuff *).
Yes, there is a problem in init_sec
// Initialize a configsection structure with a name (and 0 options)
void init_sec(configsection *sec, char *name) {
sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
}
You're just copying the name pointer here, which means, that it points to the original storage of name. If you'd call init_sec like this
configsection foobar()
{
configsection sec;
char name[80];
get_name(name);
init_sec(sec, name);
return sec;
}
The name pointer became invalid the moment foobar returned. You need to duplicate the string and keep your private copy around. In init_sec:
sec->name = strdup(name);
But there's more. In the very first line of init_sec you're overwriting the pointer that was passed to init_sec with the one of malloc. So the new pointer never gets passed back to the calle. Either use a pointer to a pointer, don't take a configsection pointer at all (after all, you're allocating), but just return the allocated pointer: Complete corrected function:
// Initialize a configsection structure with a name (and 0 options)
configsection* init_sec(char *name) {
configsection *sec = malloc(sizeof(configsection));
sec->numopts = 0;
sec->name = name;
printf("%s\n", sec->name);
return sec;
}

Resources