I have created an abstract data type in C that is based off a structure. Inside this structure, there are pointers to other ADTs that are also based off of structures. I want to know how/if I can properly initialize the pointers on the inside and get rid of my memory access violation errors. The code is below:
typedef struct insideADT1_S{
int someConstant1;
int someArrray1[500];
} insideADT1_T
typedef struct insideADT2_S{
int someConstant2;
int someArray2[500];
} insideADT2_T
typedef struct outsideADT_S{
insideADT1_T *insidePTR1;
insideADT2_T *insidePTR2;
} outsideADT_T
I create the outside structure and pass it to a function. Inside the function, I try to get one of the inside members, and I crash and get a memory access error. An example is below:
outsideADT_T *outsidePTR;
SomeFunction(&outsidePTR);
The inside of SomeFunction looks like:
void SomeFunction(outsideADT_T *outsidePTR){
//===Fill Array of Inside ADT===//
for (i=0; i<500; i++){
outsidePTR->insidePTR1->someArray1[i] = i; //OOPS! Memory Access Violation! FAIL!
}
}
However, accessing like this gives me memory access violations. Note that I can solve the problem by using the structure versions, instead of the ADTs, and not defining pointers to those structures. For instance:
typedef struct outsideADT_S{
struct insideADT1_S insideSTC1;
struct insideADT2_S insideSTC2;
} outsideADT_T
void SomeFunction(outsideADT_T *outsidePTR){
//===Fill Array of Inside ADT===//
for (i=0; i<500; i++){
outsidePTR->insideSTC1.someArray1[i] = i;
}
}
Works fine. Why does the first method fail when the second one doesn't? What am I doing wrong the first time, and how can I fix it?
You call SomeFunction with a pointer to a pointer to an outsideADT_T structure (double reference), whereas SomeFunction is declare to just take a pointer to that structure (single reference). Try this:
outsideADT_T outsidePTR; // <-- notice the lack of '*'
SomeFunction(&outsidePTR);
Furthermore, you dereference insidePTR1 without initializing it. You'll need to allocate some memory for it at the beginning of SomeFunction:
outsidePTR->insidePTR1 = malloc(sizeof(insideADT1_T));
Same goes for insidePTR2.
Related
Answer (see below): When accessing a struct with a pointer, one needs to use the arrow operator "myStruct->structVariable" which is the equivalent to "(*myStruct).structVariable" which is called dereferencing a pointer (getting the value instead of the address). When accessing the struct directly one uses "myStruct.structVariable".
I'm pretty new to C and pointers and am trying to do the following:
I'd like to access an array of structs which is part of another struct. The struct is a pointer which gets passed to a function, in which i would like to access it.
Student has an array of structs which 10 Lectures (also a struct). To simplify the process of adding lectures to a student, i would like to be able to call the function "addLectureToStudent()" and passing the necessary arguments and assign the values to the array of lectures.
typedef struct Lectures {
char name[20];
} Lecture;
typedef struct Students {
char name[20];
Lecture lectures[10];
} Student;
void addLectureToStudent(Student * stud, int position, char lecture_name[20]){
strcpy(stud->lectures[position]->name, lecture_name); //This line doesn't work as expected
}
int main(void) {
Student markus;
strcpy(markus.name, "Markus");
markus.matrikelnummer = 12089548;
addLectureToStudent(&markus, 0, "Programming");
}
My problem is, that when wanting to access strcpy(stud->lectures[postition]->name, lecture_name) it tells me that stud should be a pointer but isn't (thats the best translation i can come up with. It is originally in german..). How do i access the array of lectures properly in this case?
stud->lectures[position] is Lecture, so you should use ., not ->, to access that.
strcpy(stud->lectures[position].name, lecture_name);
There are two ways to access the structure elements, usng a pointer to a structure.
Using dereference operator and dot (* and .)
strcpy((*stud).lectures[position].name, lecture_name);
Using arrow (->)
strcpy(stud->lectures[position].name, lecture_name);
markus.matrikelnummer = 12089548; This is wrong, because there is no element matrikelnummer in structure Student.
General syntax is pointer_name->variable_name and (*pointer_name).variable_name
I am working on C code that reads in binary files, and organises the data contained in these files into a struct before processing. In its most concise form, the main function is structured as follows:
1) read_hgf_file
2) process_contents
3) free_allocated_memory
Because the data consists of recordings at different points in space, the most convenient is to organise the data in a struct with arrays. I have included the definition of this struct in a header file "read_hgf.h", which looks as follows (I am using MSVS 2017):
#pragma once
struct HGF {
int32_t Nrows;
int32_t Ncols;
int32_t Np;
float *data;
float *xcoords;
float *ycoords;
float *zcoords;
};
The first three fields help to define the size of the latter four.
In my main function, I call a function that fills these fields with the data from the binary file, which works fine. At the end now, I want to free the dynamically allocated memory associated with this struct. Because it looks messy if I free these arrays one-by-one in the main function, I want to wrap this functionality in a function free_hgf(). Did I understand correctly that I have to free these fields one-by-one, just as they are declared? Would the following be a correct way of doing that, or am I violating any C rules/best practices (particularly related to the combination of the * and -> operators)?
function:
#include "read_hgf.h"
void free_hgf(struct HGF **hgf) {
free((*hgf)->zcoords);
free((*hgf)->ycoords);
free((*hgf)->xcoords);
free((*hgf)->data);
*hgf = NULL;
}
Called from main as follows:
#include "read_hgf.h"
struct HGF hgf;
struct HGF *hgfPtr = &hgf;
free_hgf(&hgfPtr);
Thanks in advance!
I assume that the function which fills HGF structure is written by you and members of HGF structure are allocated with malloc, like
void read_hgf(struct HGF * hgf)
{
...
hgf->data = malloc(...);
hgf->xcoords = malloc(...);
hgf->ycoords = malloc(...);
hgf->zcoords = malloc(...);
...
}
Usage of the structure would be
struct HGF hgf;
read_hgf(&hgf);
...
free_hgf(&hgf);
and freeing part,
void free_hgf(struct HGF * hgf) // single pointer is enough to pass a structure
{
free(hgf->zcoords);
free(hgf->ycoords);
free(hgf->xcoords);
free(hgf->data);
// clear members
hgf.data = NULL;
...
}
Remember if you allocated memory N times (with malloc, realloc, ...), after you've done using them, you must call free N times.
I'm going to try and keep this as brief as possible.
So I have two structs:
typedef struct someStruct named;
struct someStruct {
void *key;
void *value;
};
typedef struct anotherStruct namedToo;
struct anotherStruct {
named **table;
unsigned int size;
};
Okay great, now ingore any possible mistakes above, this is uneditable code.
Now I have two methods:
namedToo *init(float ignoreThis) {
namedToo *temp;
temp = malloc(sizeof(namedToo)); //some memory for the second struct
temp->table = malloc(sizeof(named)*100); //lets say this 100 is for 100 buckets/cells/named elements
return temp;
Method 2:
int insert(namedToo *temp, void* key, void* value) {
temp->table[0]->key = key; //My problem, I need to access the value and key inside named from the pointer inside namedToo. How can I do this?
}
The comment has my problem :
My problem, I need to access the value and key inside named from the pointer inside namedToo. How can I do this? I would need to change and grab value/key on their own from time to time.
The declaration named **table; says table is pointer to a pointer to named, or alternately an array of pointer to named. The latter is you seem to intend.
This allocation:
temp->table = malloc(sizeof(named)*100);
Allocates space for 100 named, but what you need are 100 named *, and each of those must point to a named. Given the definition of named this is likely enough space, however at this point you have an array of uninitialized pointers. Attempting to access them results in undefined behavior, which in this case manifests as a core dump.
You need to allocate space for an array of pointers, then initialize each of those to a single dynamically allocated instance of named. So you should be allocating space like this:
int i;
temp->table = malloc(sizeof(named *)*100);
for (i=0; i<100; i++) {
temp->table[i] = malloc(sizeof(named));
}
Then your insert method should work properly.
As part of a school assignment, I am given a structure with a double pointer to another structure inside it. I will need to be able to access the members of the nested structure within a function, but am having no luck doing so.
Here is the code I have been given
#include<stdio.h>
#include <stdlib.h>
/*Given code, do not change */
typedef struct
{
char* ID;
char* PassWord;
}Account, *pAccount, **ppAccount;
typedef struct
{
unsigned int numAccounts;
ppAccount accounts;
}FleaBay,*pFleaBay;
void FleaBayInit(pFleaBay); /* Initialise the FleaBay instance */
int main(void)
{
FleaBay e;
FleaBayInit(&e); /* Call to the function */
return 0;
}
/* end of given code */
Here is my attempt:
void FleaBayInit(FleaBay *pFleaBay){ /* Initialise the FleaBay instance */
Account ac1 = {"test1", "test2"}, *pac1 = &ac1;
pFleaBay ->numAccounts = 0;
pFleaBay ->accounts = &pac1;
}
I'm having no trouble accessing the member within the non-nested struct, but I cannot figure out how to access the members of the nested Account structure. Thought that maybe I would need to create an Account object first, point to it, and assign the value of the pointer to the accounts member within pFleaBay, but when I test with printf("%s",pFleaBay->accounts);, I get some random characters.
In the structure
typedef struct
{
char* ID;
char* PassWord;
}Account, *pAccount, **ppAccount;
ppAccount is a pointer to a pointer, which is often used to represent a dynamic array of pointers.
In the second structure
typedef struct
{
unsigned int numAccounts;
ppAccount accounts;
}FleaBay,*pFleaBay;
you have the number of the accounts, which would be the number of the elements in the dynamic array. So, in your code you could access one of the accounts using the syntax pFleaBay->accounts[n]. This means that you would want to allocate an array of pointers in your function either using malloc or calloc.
pFleaBay->accounts = calloc(pFleaBay->numAccounts, sizeof(pAccount));
Then you can allocate each of the accounts.
In your FleaBayInit(), ac1 is a local variable, and pac1 is initialized as a pointer to ac1. As a local variable, ac1's lifetime is limited to one function call. After the function returns, ac1 no longer exists, and any pointer that points to it becomes invalid.
Moreover, FleaBay.accounts is an Account **, but you try to assign an Account * to it (pac1). Not only does that pointer become invalid when the function returns, it isn't even the correct type. This is actually odd; I don't see any reason why FleaBay.accounts should not be simply an Account *.
Edited to add:
On second thought, FleaBay.accounts could be an Account ** because it is meant to point to a dynamic array of Account *, as opposed to a dynamic array of Account. That would offer some advantages, particularly if Account objects must be independent of FleaBays.
In that case, the simplest way to initialize a FleaBay would probably be this:
void FleaBayInit(FleaBay *pFleaBay){ /* Initialise the FleaBay instance */
pFleaBay->numAccounts = 0;
pFleaBay->accounts = NULL;
}
Whether that is actually appropriate, however, depends on how you intend to implement other code that manipulates FleaBays -- especially code that adds or removes accounts.
Okay so I'm having an issue with a current assignment (trust me this is a minuscule part of it) as we are required to write in C code and not C++, and we are not allowed to change certain parts of code. So I have a struct defined:
typedef struct someStruct {
int what;
int something[MAX];
int another[MAX];
} someType;
in main() I initialize all the values in a defined struct:
someType whatever, *whatptr;
EDIT:of course set the pointer to the struct, trying to simplify the code for the example It is present in my code already
whatptr = &whatever;
whatever.what = 0;
// initialize both arrays to hold 0 at all indexes
// Then I must call a function progRun()
progRun(); //I need to pass struct 'whatever' in some way
Now progRun() looks like this:
void progRun(){
printWhat(&whatever);
if (whatever.what == 0) {
//do stuff
}
}
I can't change anything inside this code except what parameters to pass inside the progRun() function and I can add stuff before printWhat(). I've tried changing progRun to
void progRun(someType *stptr)
then calling it in main as
progRun(whatptr);
but this causes a stack overflow issue for some reason, I've tried stepping through with a debugger and it only occurs when the function is called. Is there a better way to pass the 'whatever' struct to the function so it can be passed into progRun() and printWhat() and can access 'whatever.what'?
Any help would be greatly appreciated! in the meantime I'll try to figure it myself if I can.
EDIT: Something else must be wrong in the code even though everything else has compiled and ran perfectly fine until this code was added. If I can break down the code and find out what's wrong I'll update the question. And no I cannot post the whole code as it is an assignment (this isn't the goal of the assignment trust me it focuses on data forwarding and more, just need to get this basic thing working) Thank you for help everyone.
EDIT: the MAX number used in the struct for something[MAX] and another[MAX] was extremely large ( I left my desktop that I started this project with back home, I'm currently using an old laptop that can't handle large arrays). All the answers below, and some of the stuff I used before now works fine.
void progRun(someStruct *ptr) {
someStruct whatever2 = *ptr;
printWhat(whatever2);
if (whatever2.what == 0) { ...
}
whatptr = &whatever;
progRun(whatptr);
Your problem was that:
you need to pass a pointer to whatever, yet you were passing a variable (whatptr) that had absolutely nothing to do with whatever.
You need to first assign the pointer to whatever into your pointer variable.
You are not dereferencing the pointer in the function
Alternately, get rid of pointer variables:
void progRun(someType *stptr) {
printWhat(*stptr);
if (stptr->what == 0) { ...
}
progRun(&whatever);
Instruction
someType whatever, *whatptr;
is the problem:
*whatptr will not point to the struct whatever unless you do the assignment as follows:
whatptr = &whatever;
Alternatively you could dynamically allocate memory on the heap for a pointer to your struct whatever by using the malloc() function and pass the pointer returned by malloc to the function progrun:
whatptr = (someType*) malloc ( sizeof(someType) );
if (whatptr == NULL) exit (1);
//whatever you need to do with your code
progrun(whatptr); // call function like this
In this case of course you will need to dereference your pointer to access member elements of the struct by using the arrow -> operator:
whatpr->what = 0; // for example
Also, check these tutorials to understand both approaches:
link 1
link 2
If you can't change print and if statements then you should pass your function a copy of your struct:
void progRun( someType whatever ){ // <---Passing by copy
printWhat(&whatever);
if (whatever.what == 0) {
//do stuff
}
}
and in your main() you should just call the function like this:
someType whatever;
//assign values to members of the struct
progRun(whatever);
and do not need at all to define and assign a pointer to the struct.
Though passing variables to functions by copy (especially when they are objects composed by many variables such as a struct is) is not a good behaviour:
it will require an overhead to copy all member elements
your copy will have a limited scope, which means that any change you do to the variable inside of the function will be lost when your function ends and will not be reflected on variable at main scope