Structures, malloc.. I couldn't be more confused [closed] - c

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.

Related

When to make pointer point to a struct on the heap vs on the stack? [duplicate]

This question already has answers here:
Why, or when, do you need to dynamically allocate memory in C?
(3 answers)
Closed 5 years ago.
#include <stdio.h>
#include <stdlib.h>
typedef struct foo {
char* text;
int num;
} foo;
int main(void) {
foo* a = malloc(sizeof(foo));
a->text = "Something";
a->num = 4;
printf("%s %d\n", a->text, a->num);
foo b;
b.text = "Something";
b.num = 4;
foo* c = &b;
printf("%s %d", c->text, c->num);
return 0;
}
Both print the exact same thing. The only difference between foo* a and foo* c is where each one points to. Which one should be preferred? I usually see malloc() more but I don't understand why.
I think you should malloc() only for bigger data. You should consider that malloc() needs more time because it must find search for a data block in the heap and reserve it. If you use the struct on stack this is not necessary. So it really depends on what you are doing.
Edit: Also you should think of the scope of the variable. If the struct is needed only within the function I would prefer the stack.
Heap-allocated data is easier to share with others (i.e. across function boundaries), especially when the function that creates an object needs to have it usable when that function has exited. This is not possible with non-heap data (except when using static but that creates problems too), which can be rather limiting.

qsort not working c program [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I am trying to sort an array of names via qsort.
This is my code
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int myCompare (const void * a, const void * b ) {
return *(char*)a - *(char*)b;
}
int main(void) {
int i;
char fileArr[] = {"inputbv", "inputa","inputzef",};
int stringLen = sizeof(fileArr) / sizeof(char *);
qsort(fileArr, stringLen, sizeof(char *), myCompare);
for (i=0; i<stringLen; ++i)
printf("%d: %s\n", i, fileArr[i]);
}
This code doesn't print anything at the end. It just ends so it seems like it deletes the entries in the char array
First off, you're missing a *:
char *fileArr[] = {"inputbv", "inputa","inputzef",};
This doesn't explain why you're not sorting correctly, which is a different issue, but it does explain why you're getting no output. (A validating compiler, like gcc -Wall, would have told you that that declaration is invalid without that missing star.)
There are a number of other issues here, though. First off, as one of the commenters alluded to, the myCompare() function is declared with the right type, but it doesn't quite do what you think it does:
int myCompare(const void *a, const void *b)
{
...
}
That's because qsort() passes the address to each chunk of data, not the chunk of data itself. The chunks of data in this case are pointers to character arrays, so qsort() is going to pass pointers to pointers to your comparison function. Those aren't single stars there; they're actually two stars in disguise.
Secondly, comparing pointers does you no good: The pointers are, almost by definition, random values. Your comparison function, as written, even if you corrected it for the number of *'s that are supposed to be there, would still be wrong:
/* Don't do this. */
return *(char **)a - *(char **)b;
That's literally more-or-less "sort by the random locations of these strings in memory," which doesn't help you at all for putting them in order.
The right thing to do is not to add yet another star (writing **(char **)a - **(char **)b literally means "compare the first characters against each other"). The right thing to do is invoke strcmp() to compare the two strings lexically:
int myCompare(const void *a, const void *b)
{
return strcmp(*(char **)a, *(char **)b);
}
That's what you should be using.

Passing Struct * by reference C [closed]

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 6 years ago.
Improve this question
+I'm trying to pass from the main an array of CustomStruct by reference, but im doing something wrong:
I think i'm asking correctly for memory, but it doesn't seem so, because when i try to force some values, i get core dumped and i absolutely don't know why.
void readFile(OwnStruct **restaurant){
FILE *f;
int numTaules = 0;
f = fopen("hello.txt", "r");
if(f == NULL){
printf("Error at opening!\n");
exit(0);
}
fscanf(f,"%d",&numTaules);
//Asking for memory
*restaurant = (OwnStruct*)malloc(sizeof(OwnStruct) * numTaules);
//From here, at some point: Core Dumped
restaurant[0]->ocupades = 1;
restaurant[0]->disponibles = 2;
restaurant[1]->ocupades = 3;
restaurant[1]->disponibles = 4;
printf("%d\n",restaurant[0]->ocupades);
printf("%d\n",restaurant[0]->disponibles);
printf("%d\n",restaurant[1]->ocupades);
printf("%d\n",restaurant[1]->disponibles);
}
int main(){
typedef struct(){
int ocupades;
int disponibles;
}
OwnStruct *restaurant;
readFile(&restaurant);
return 0;
}
You are referencing the array wrong:
So far so good:
*restaurant = (OwnStruct*)malloc(sizeof(OwnStruct) * numTaules);
This is wrong:
restaurant[0]->ocupades = 1;
It should be:
(*restaurant)[0].ocupades = 1;
You must dereference the pointer to your pointer. That expression then points to the first element of the allocated array. The parentheses are needed, because postfix operators like EXPR[0] take precedence over unary operators like *EXPR, so *EXPR[0] is treated as *(EXPR[0]).
Suggestion: Work with a local pointer which is just Ownstruct *ptr. Then, just before returning from the function, store that pointer:
*restaurant = ptr;
Then you can just have ptr[0]->field = value type code in your function.
Your problem is that your function
void readFile(char fileName[], OwnStruct **restaurant)
expects two parameter, but you pass just one.
readFile(&restaurant);
Just write
readFile("myFile.txt", &restaurant);
or define your function as
void readFile(OwnStruct **restaurant)
The example you give should not currently compile - readFile expects a filename and a pointer to a pointer of OwnStruct. Your main is just providing the pointer.
The struct should defined somewhere at the top (before its use in main and readFile)
readFile is also reading numTauls from a file but then assuming it is at least 2 when assigning values to the allocated memory.

Allocating memory through calloc in C [closed]

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 6 years ago.
Improve this question
I am simply testing what would be the output if I try to dereference a pointer, which points to out of range of dynamically created memory using calloc() and expecting memory fault or some garbage value instead. It is giving 0 as output, which is basic feature of calloc() that it intializes allocated memory with '0', or is it just due to undefined behavior?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = NULL;
p = (int *)calloc(10, 8);
if(p != NULL)
{
printf("\n successfully allocated memory ");
}
else
EXIT_FAILURE;
printf("\n Thirty first element of memory is %d \n",p[30]);
}
Result :
successfully allocated memory
Thirty first element of memory is 0
You are trying to access p + 30 * sizeof(int) which is p + 120 while you have allocated only 8 * 10 = 80 bytes, so max address you can access is p[19]
From a language perspective, accessing out of bounds memory is undefined behavior, meaning that anything can happen.
One possible explanation for that particular behavior is that most operating systems will zero out any memory before they give it to your process, independently of what function you where using internally (this is a security measure, so you can't read data that was used by other processes).
To get garbage data, you usually have to have used and freed the same memory before inside your program (in which case it retains its old value). Or of course, if your index is so far off that you are indexing into a neighboring data structure.
The reason your program didn't just crash is that malloc (and similar functions) usually request much more memory from the os, than what you are requiring and use the surplus memory the next time you call malloc. So from the OS perspective you are accessing valid memory, and there is no reason to terminate your program.
Accessing out of range memory is Undefined Behaviour. Hence the value which you get can be 0 or 1 or Batman
The point is, you cannot ask any explanation or reason for things that are undefined. Anything can happen in such a scenario.
Also, you would get a seg fault if you try to access a memory location which your program is not allowed to access. That may not be the case always when you access out of bounds memory. It can lie well inside the user memory area of the program.
I think windows zeroes a freed page before making available for allocation. Have fun with the code below.
#include<stdio.h>
#include<stdlib.h>
#include <windows.h>
#include <signal.h>
int g = 0;
unsigned long long* p=NULL;
void signal_handler(int ssc)
{
printf("Error %d \n", ssc);
printf("segfault after %llu bytes",g*8);
printf("should i go backwards? press enter");
getch();
g=0;
do
{
printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
Sleep(1);
g--;
}
while(1);
}
int main ()
{
if(SIG_ERR == signal(SIGSEGV, signal_handler) ) {printf("error seting signal handler %d\n",SIGSEGV);}
p = (unsigned long long*)calloc(10,8);
if( p!= NULL)
{
printf("successfully allocated memory\n");
}
else
{
EXIT_FAILURE;
}
do
{
printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
Sleep(2);
g++;
}
while(1);
return 0;
}

Issue with PHP pop( ) function [closed]

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 3 years ago.
Improve this question
So I'm having an issue with my pop() function, when running my program, the first time I call the pop() function it returns the item no problem, but when it tries to pop the second item in succession, it fails. I can't seem to figure out why, is there something I'm missing in my function?
#define DEFAULT_CAPACITY 16
struct stack {
size_t capacity;
size_t size;
stack_item *data;
};
stack *new_stack (void) {
stack *this = malloc (sizeof (stack));
assert (this != NULL);
this->capacity = DEFAULT_CAPACITY;
this->size = 0;
this->data = calloc (this->capacity, sizeof (stack_item));
assert (this->data != NULL);
return this;
}
void free_stack (stack *this) {
assert (empty_stack (this));
free (this->data);
free (this);
}
static bool full_stack (stack *this) {
return this->size == this->capacity;
}
static void realloc_stack (stack *this) {
size_t old_capacity = this->capacity;
this->capacity *= 2;
this->data = realloc (this->data, this->capacity);
memset (this->data + old_capacity, 0, old_capacity);
assert (this->data != NULL);
}
void push_stack (stack *this, stack_item item) {
if (full_stack (this)) realloc_stack (this);
//increase size of stack
this->data[this->size] = item;
this->size++;
}
stack_item pop_stack (stack *this) {
assert (! empty_stack (this));
printf("Stack size: %lu\n", this->size);
return this->data[this->size--];
}
Depends on what you mean by "fail".
There are numerous reasons it could fail, such as (by no means exhaustive):
code for pushing data is incorrect.
you haven't created a big enough capacity.
you haven't pushed enough items to pop (stack underflow).
The first thing you should do is create a dump_stack function for debugging, along the lines of:
void dump_stack (char *desc, stack *this) {
printf ("%s: size/capacity: %lu/%lu\n",
desc, this->size, this->capacity);
for (size_t idx = 0; idx < this->size; idx++) {
// print out this->data[idx], depends on data type
}
}
This will greatly assist in figuring out where your problem lies, if you call it after each stack operation (push, pop, peek, clear, dup, rot, 2dup, 3rot, and so on).
Now that you've added some more code, there's a few things you need to look at.
First, your stack_item type. Unless this is exactly the same size as char, your memory allocation functions are incorrect. For example, if it's a four-byte integer, you will need to allocate four times as much memory as you currently are. This can be fixed by multiplying the allocations by sizeof(stack_item).
You've done this with the initial calloc call (because you have to provide a size for that) but not in the subsequent realloc ones.
Second, in your realloc_stack function, you really should assert before doing the memset. If, for some reason, the reallocation fails, it's not a good idea to do anything to the memory.
Third, relying on assert to catch errors that may or may not happen at runtime is a bad idea. That's because assert typically does nothing in non-debug code (based on NDEBUG) so, if you run out of memory, you're not going to catch that. You probably need to provide your own error handling stuff in conjunction with exit() (for example).
I'm also not really a big fan of library-type code pulling the rug out from underneath you if it has a problem - I always prefer to have it return an indication to the caller and let that decide what to do (that's why I'll never use GMP in production code since it does exactly that when it runs out of memory).
Fourth, using calloc and memset here is almost certainly a waste since your code knows where the stack end is based on size. Whether those entries above size but below capacity are set to 0 or some arbitrary value is irrelevant since you'll never use them without first setting them to something (with a push operation).

Resources