Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
struct atom {
int x;
int y;
int z;
double mass;
};
struct molecule {
struct atom *member;
int natoms;
};
struct system {
struct molecule *fragment;
int nfrags
};
struct system sys;
sys.nfrags=get_number_of_fragments;
????
The system has some number of molecules, each of which has some number of atoms. I don't know how to allocate these things. If I allocate sys.fragment first, it seems like the sizeof(molecule) is undefined since I haven't yet defined the number of atoms (so how can it have a size?). If I try to define the number of atoms first, how do I specify which fragment I'm mallocing for?
I have functions that will return the number of atoms for any molecule/fragment as well as the number of fragments, but am stuck on where to go from here.
AFAIK sizeof(X) cannot be "undefined". In this example, sizeof(molecule) is well defined as the amount of memory it takes to store one molecule instance: One atom Pointer (Note: not the size of any array that you may put here, just the size of the pointer) and one int. So it is perfectly fine to do it the first way and allocate your sys.fragment first:
sys.fragment = malloc(sys.nfrag * sizeof(sys.fragment));
sys.fragment = calloc(sys.nfrag, sizeof sys.fragmemt[0]);
or
sys.fragment = malloc(sys.nfrag * sizeof sys.fragment[0]);
when performance matters (but do not forget the check for overflow!).
malloc(sizeof(system)) Easy as that
You basically have a:
size = X;
first = malloc(X * sizeof(First));
first->second = malloc( N * sizeof(Second));
and so on
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
My name is Bob and I am a three-star programmer. Well, more accurately, I'm trying not to be. I have read a lot on the internet and this site about how "three-star programmer" is a Very Bad Thing. And I can see why. I have read very little (very little that's comprehensible, anyway) about how to avoid it. I mean, there are data sets out there that simply need three or more indices to access their values in a sane manner. So how do I deal with such a set?
I remember seeing a C macro a while back that allows you to store such a data set in a 1D array, and then access the data with three indices, something to the effect of a(i,j,k) is expanded to a[i*NZ*NY + j*NZ +k] but I can't remember how to write it and can't find it on the internet. Anyone know, or have a better idea?
My C is very poor, but wouldn't this simply be:
struct intArray3d {
int NX;
int NY;
int NZ;
int data[]; //or maybe it's data[0]?
};
intArray3d* newIntArray3d(int NX, int NY, int NZ) {
int dataBytes = NX*NY*NZ*sizeof(int);
intArray3d* array = malloc(sizeof(intArray3d) + dataBytes);
array->NX = NX;
array->NY = NY;
array->NZ = NZ;
memset(array->data, 0, dataBytes);
return array;
}
int intArray3dGet(intArray3d* array, int x, int y, int z) {
assert(x<array->NX);
assert(y<array->NY);
assert(z<array->NZ);
return array->data[x*NY*NZ+y*NZ+z];
}
void intArray3dSet(intArray3d* array, int x, int y, int z, int value) {
assert(x<array->NX);
assert(y<array->NY);
assert(z<array->NZ);
array->data[x*NY*NZ+y*NZ+z] = value;
}
Notably:
This avoids unnecessary allocations. The metadata and all of the data happens in a single allocation.
It's super easy to allocate and free.
This tracks the various dimensions alongside the data.
Nobody is going to see a int*** and wonder how big each dimension is. The data already knows.
It's very easy to use correctly.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
How do I dynamically create an array of struct in a function in C?
The struct:
typedef struct Track {
char artist[LONGSTR];
char file[LONGSTR];
int id;
int isAlbum;
char name[LONGSTR];
int pos;
char title[LONGSTR];
int time;
} Track;
The function:
int
processplaylist (struct Track** tracks, char* resp)
{
//count the tracks to return
//allocate space for the resulting tracks
*tracks = mem_alloc (count * sizeof (struct Track));
//process each track
return count;
}
And the usage:
char playliststr[] = "file: some-mp3\nTitle: Dire Straits - Romeo And Juliet\nName: TheRadio\nPos: 0\nId: 12\nOK\n"
struct Track* tracks = NULL;
int count = mpd_processplaylist(&tracks, playliststr);
Within the function the tracks are nicely processed and upto the return statement tracks points to the right location to get to the tracks. Most questions I have seen are about arrays to values, not structs.
This answer returns an array of structs, but I would like to return the count (question of style) and return the array through the parameter.
What is going wrong? After the function returns, count has the right value and tracks is still NULL.
As the not so nice people pointed out by down voting the question, the question is too broad and vague. I apologize for that, I was desperate.
As the nice people in the comments confirmed, the code is correct. Even though the debugger showed that just before the return statement everything was OK and after returning to the usage it was not.
By commenting out code lines and logging a lot, there are two things to note.
Within the function, you must refer to the individual tracks as (*tracks + i) or, for example, (*(*tracks + i)).file. Indeed, not shown in the sample code. I had tried *(tracks + i), &tracks[i] and tracks + i, which in the debugger all seemed to work and did not cause immediate errors. I guess the code messed up memory that only came out after the return.
Outside the function, in the usage, you refer to the tracks as an array, as tracks[i] or, for example, tracks[i].file.
I hope that at least my answer helps.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have:
typedef struct{
int *stack;
int *stack_ptr;
}MyStruct;
then somewhere else I do:
MyStruct *temp = malloc(sizeof(MyStruct));
temp->stack = malloc(1024) //allocate 1024 bytes
temp->stack_ptr = temp->stack; //stack_ptr points to beginning of stack
temp->stack_ptr += 800; //move stack_ptr down towards bottom of stack
I'm trying to make sense of the debugger output and I don't think this is right, but I can't tell for sure. I just want to have a stack within my struct and then a stack pointer within this stack that I can manipulate.
EDIT: Okay, the part about adding 800 makes sense. I guess what I'm having trouble understanding is after I allocate 1024 bytes for temp->stack, how do I go about inserting something down towards the bottom of that stack? Do I even need to have the stack_ptr or is there a way to offset stack variable.
Your problem is likely that you think
temp->stack_ptr += 800; //move stack_ptr down towards bottom of stack
would advance your stack pointer to the 800th stack entry. It doesn't, it moves the stack pointer to 800 * sizeof(int) bytes (likely 3200), while you allocated only 1024 bytes.
If you need to dynamically allocate n items of something, the idiomatic C code is
sometype *foo;
/* ... */
foo = malloc (n * sizeof (*foo));
The sizeof multiplication is usually omitted for pointers-to-char since sizeof(char) is 1 by definition of the C Language Standard.
temp->stack = malloc(1024) //allocate 1024 bytes
Should be:
temp->stack = malloc(1024 * sizeof(int)); //allocate 1024 bytes
What exactly is your problem ??
Edit
Let me explain what i meant by that:
Your are trying to move your pointer of 800 blocks (800 * sizeof(int)) but you only allocate 1024 = 1024 / sizeof(int) blocks
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
Here is the whole code I have so far for the assignment I am having trouble with:
// This program takes a quadratic from the user, and prints the solution(s) if they exist.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
// Define quadratic structure
typedef struct quadratic{
float a, b, c;
float discriminant;
float real_root_1;
float real_root_2;
float complex_root;
} Quadratic;
// 'Redefine' malloc to also check allocation of memory when called, as suggested
void xmalloc(size_t n){
void *p = malloc(n);
if (p == NULL) {
printf("\n ERROR: Unable to allocate memory! \n");
exit(1);
}
return p;
}
// Following example code in lecture notes
Quadratic *newquadratic() {
Quadratic *q = xmalloc(sizeof *q);
return q;
}
int main () {
return 0;
}
Now I'm not too sure what I'm doing, but I'll ask about that after the problem this code has first. On the "Quadratic *q = xmalloc()" line I get the error "Void value not ignored as it ought to be", however this code was basically copied out the lecture notes and the variables names changed! (as we were suggested to do..). I tried removing the void tags in xmalloc, which then started complaining of undefined variables, so I'm really not sure what's going on.
More generally, I'm confused as hell about some parts of this: Namely, the function "Quadratic *newquadratic()". Why the hell is there a star there!? How can a pointer be a function..? Not only that, but it would seem if I remove the star, everything is ok only if I star the return, "return *p;". It would seem that this function can only return pointers, but I defined Quadratic as a variable type (structure), so.. why would it want to return a pointer rather than a 'quadratic'?
As things currently stand you xmalloc() function is useless. It allocates memory but does not return anything so no-one can use the allocated memory.
Possibly you made a transcription error:
void * xmalloc(size_t n){
void *p = malloc(n);
if (p == NULL) {
printf("\n ERROR: Unable to allocate memory! \n");
exit(1);
}
return p;
}
If you have xmalloc declared as returning a void* you can then return something and use it in the calling function.
The implication to me is that you don't understand the difference between a void and a void*. A function returning a void is returning nothing, there is no value to use. A void* on the other hand is a pointer to anything, and hence is a great representation of a generally useful block of memery allocated by malloc.
xmalloc should return a pointer if you're using it like malloc.
Then you use it so allocate N bytes of memory for a Quadratic structure.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
So, I'm a C# guy trying my hand at learning C. As a first (personal) project I am attempting to write a basic coordinate geometry library.
Question: Is it again best C programming practices to allocate memory on the heap behind the scenes instead of letting the programmer who is targeting the library do it?
For example, my 'point' struct & related methods:
point.h
/* A basic point type. */
typedef struct point
{
float x;
float y;
float z;
char *note;
}point;
/* Initializes a basic point type. [Free with free_point method] */
point *create_point(float pos_x, float pos_y, float pos_z, char *_note);
/* Frees a point type. */
void free_point(point *_point);
/* Finds the midpoint between two points. */
point *midpoint(point *pt1, point *pt2);
point.c
#include "point.h"
/* Initializes a basic point type. [Free with free_point method] */
point *create_point(float pos_x, float pos_y, float pos_z, char *_note)
{
point *p;
size_t notelen = strlen(_note);
p = (point*)malloc(sizeof(point));
p->x = pos_x;
p->y = pos_y;
p->z = pos_z;
p->note = (char*)calloc(notelen + 1, sizeof(char));
strcpy_s(p->note, notelen + 1, _note);
return p;
}
/* Frees a point type. */
void free_point(point *_point)
{
free (_point->note);
free (_point);
}
/* Creates a midpoint between two points. */
point *midpoint(point *pt1, point *pt2)
{
float mid_x = (pt1->x + pt2->x) * 0.5f;
float mid_y = (pt1->y + pt2->y) * 0.5f;
float mid_z = (pt1->z + pt2->z) * 0.5f;
point *p = create_point(mid_x, mid_y, mid_z, "Midpoint");
return p;
}
Notice that I creating the struct 'point' on the heap FOR whoever implements/uses my lib (in all honesty, this project is just for me and for learning, nevertheless...) via the create_point() method. Is this poor practice? It feels like I am forcing the user into programming a certain way. Same goes with the midpoint() method. Again, you must use pointers to a 'point' struct.
I was unable to find exact questions regarding C library design on SO, but please point me in the right direction if applicable.
Thanks.
It's preference, really. I usually subscribe to letting the user allocate the memory for the object however they wish, and then initializing the members for them.
/* here a non-zero return value might indicate if for example
* we failed to allocate memory for note */
int point_init(struct point* p, int x, int y, char* note)
{
/* ... */
}
/* usage: */
struct point p;
if (point_init(&p, 1, 2, "hello")) {
/* error */
}
This gives the user the option to do things like allocate an array of points that are adjacent in memory, instead of keeping track of an array of pointers to points:
struct point mypoints[NUM_POINTS];
for(size_t i = 0; i < NUM_POINTS; ++i) {
point_init(&mypoints[i], ...);
}
EDIT:
If you want to use the Opaque Pointer strategy to hide the members of your structure from the library user, you will need to allocate the memory for them using the method you described. That's certainly a huge benefit for allocating the structure in your library.
Best practice is to code the library in such a way that the programmer can do what's fastest, since that is a forte of C. For example, the programmer might know that tens of thousands of these point structs will be needed and for the sake of keeping future accesses local might prefer to allocate all the structs in one block of memory. If your library lets the programmer pass pointers in for structs to be initialized, then he can do this. But if you insist on allocating the memory for him, he can't.