Structure initializing problem in C - c

I'm writing a program for a "Set" data structure in C.
It's working fine when one instance of Set is present, but it doesn't work when two instances of Set are present.
Also my code for removing an element is not working when the candidate is the first element.
Can someone help me?
Here is the code:
Set.h
Set.c
Test.c

First of all you passes pointer to set by value. I.e. instead of
void Set_Create (Set* set) {
set = malloc(...); // Malloc here leads to memory-leak.
//...
}
int main() {
Set *set; // Some value like 0xdeadbeef pointing somewhere
Set_Create (set);
// set have still undefined value
}
use
Set *Set_Create () {
Set *set = malloc(...);
/// ...
return set;
}
int main() {
Set *set; // Some value like 0xdeadbeef pointing somewhere
set = Set_Create ();
// set point to new memory
}
or:
void Set_Create (Set *set) {
// No malloc
/// ...
return set;
}
int main() {
Set set; // Create on stack
Set_Create (&set); // Initialize
// ...
}
I'd advice re-reading chapter on pointers (don't worry - they are considered hard but they are must for C programmers).

I suspect that you are asking us to help you with your homework, so I am not going to solve all of your code problems for you. I am only going to point out your most egregious mistake, which is the mistake you asked about -- why does the second call to your create_Set() function fail?
test.c, lines 27-28:
Set* s2;
Set_Create(s2); //.. Here error comes..
In set.c, I have trimmed it down to the meaningful code:
void Set_Create(Set* set){
if(set == NULL){
set = (Set *)malloc(sizeof(Set));
}
set->size = 0;
set->data = -1;
set->next = NULL;
}
What's happening is that both of your calls to Set_Create are overwriting some arbitrary, unpredictable, memory locations. This is a serious bug.
In the case of set1, the arbitrary pointer you have been experiencing seems to happen to point to some place in memory which can be written to. Who knows what data you are clobbering, but your data can survive in that spot for a short duration.
In the case of set2, the arbitrary pointer you are encountering is not a valid memory location for you to modify, so your program crashes.
Change your create_Set like so:
Set* Set_Create() {
Set * set = calloc(1, sizeof(Set));
set->data = -1;
return set;
}
And in test.c:
Set * set1 = Set_Create();

Related

Why is this code printing '7'

Why is this code printing '7'
Trying to understand how the Stack and Heap looks like and how does it looks in the memory allocation
public static void Main()
{
Cls a = new Cls();
a.v = 3;
Func(a);
Console.WriteLine(a.v);
}
class Cls
{
public int v;
}
static void Func(Cls a)
{
a.v = 7;
a = new Cls();
a.v = 2;
}
If you can attach a scatch of stack and heap with memory it will really appreciated
static void Func(Cls a)
{
a.v = 7; <----- This is modifying the Cls you create in Main function
a = new Cls();
a.v = 2; <----- This is a new and locally referenced Cls whose value is neither returned to the main function nor is a global variable
}
You're passing a pointer to the first Cls instance. The second one, created inside youre function, is an entirely different object.
In other words, you're printing a property value from the first object, the one pointed to by the a in Main().
When you're re-assigning the a variable to a new object inside your function, the a inside Main() still points to the original object.
I'm not sure I'm explaining this very well... :) Or perhaps I'm even misunderstanding the question?

C structure initialization before using it?

I do not understand why i have to initialize my structure before using it, i get this error in my code, i know it works if i use pointers or if i initialize the structure members, but why it does not work in this way ?
#include <stdio.h>
typedef struct human{
char name[20];
int age;
} student;
void function(student ){
printf("It's not working");
}
int main(){
student a;
function(a);
return 0;
}
I get this
Debug Error!
File: Run - Time Check Failure #3 - The variable 'a' is being used without being initialized. (Press Retry to debug the application)
and i do not get the message from my function on output
You get this error, because your debugger detect, that you are sending unitialized variable to the function. It doesn't know, what will you do with it inside of the function, so it warns you. You can see, that if you run program in release, no error will occur. Easiest solution for you, if you know, that you will initialize it lately to correct values, is just to initialize it, when creating student a = {0};
You are passing the object a by value to function. As C has only value-semantics, it can only copy values in this case. So, you initialise the parameter (even if your implementation doesn't care about the parameter) with an unitialised object, wich requires reading from that object. This is undefined behaviour, hence the compiler informs you that you are doing something illegal.
If you pass the object via a pointer, you still pass-by-value, but the value being copied is the pointer. Hence you don't have to read the actual value and your compiler wont complain.
Observe:
void flat(student s) {
s.age = 20;
}
void ptr(student* s) {
s->age = 20;
}
int main() {
student s = {"Eve", 0};
// { s.age == 0 }
flat(s);
// { s.age == 0 } --- still the same, no change
ptr(&s);
// { s.age == 20 } --- now it has changed
}

Modifying struct members through a pointer passed to a function

for instance this code:
struct test{
int ID;
bool start;
};
struct test * sTest;
void changePointer(struct test * t)
{
t->ID = 3;
t->start = false;
}
int main(void)
{
sTest->ID = 5;
sTest->start = true;
changePointer(sTest);
return 0;
}
If I was to execute this code, then what would the output be? (i.e. if I pass a pointer like this, does it change the reference or is it just a copy?)
Thanks in advance!
Your program doesn't have any output, so there would be none.
It also never initializes the sTest pointer to point at some valid memory, so the results are totally undefined. This program invokes undefined behavior, and should/might/could crash when run.
IF the pointer had been initialized to point at a valid object of type struct test, the fields of that structure would have been changed so that at the end of main(), ID would be 3. The changes done inside changePointer() are done on the same memory as the changes done in main().
An easy fix would be:
int main(void)
{
struct test aTest;
sTest = &aTest; /* Notice the ampersand! */
sTest->start = true;
changePointer(sTest);
return 0;
}
Also note that C before C99 doesn't have a true keyword.
The only question is why do you need a test pointer in a global name space? Second is that you do not have any memory allocation operations. And you have a pointer as an input parameter of your function. Therefore structure where it points to will be changed in "changePointer".
1) First thing your code will crash since you are not allocating memory for saving structure.. you might need to add
sText = malloc(sizeof(struct test));
2) After correcting the crash, you can pass structure pointer and the changes you make in changePointer function will reflect in main and vizeversa..
3) But since you are not printing anything, there wont be any output to your program..

How to dynamic realloc a global variable with C

Ok, this is my first C program since "hello wolrd" and I need some help with realloc. I have a dynamic array defined as a global variable.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
double *close = NULL;
unsigned int closesize = 0;
And I want to increase the array in a method. But I get a seg fault error. I have tried it like this:
void addInputParamReal(
OCIExtProcContext *ctx
//,unsigned int paramIndex
//,OCINumber *value
,double value
)
{
double dtemp;
double **myclose = &close; // last try, make a pointer to my outside array
//OCINumberToDouble(ctx,value,&dtemp);
dtemp = 12.4; //just now
//Not good
*myclose = (double *) realloc (*myclose,(closesize+1) * sizeof(double));
close[closesize++] = dtemp;
}
Can you please help me out?
Thanks
Chris
Extending by 1 every time is going to be somewhat inefficient. Usually, you'd extend by a chunk (either fixed size or a percentage of the current size), and then keep track of the physical size (closesize) separately from the array index (call it closeindex):
if (closeindex == closesize)
{
double *tmp = realloc(close, sizeof *tmp * (closesize + EXTENT));
if (tmp)
{
close = tmp;
closesize += EXTENT;
}
else
{
// panic
}
}
close[closeindex++] = ...;
You can figure out a way to make this read a little more elegantly, I'm sure.
Some reallocs implementations may let you pass in an initial starting NULL and some may not. On linux, for example, a NULL should be allowed for example but I don't believe that's an absolute truth everywhere. You should try, in the beginning of your program, to initialize it using a regular malloc() call first.
Everyone else is correct, though, resizing by 1 is very inefficient. Knowing how your data is going to grow, roughly, is very important. If nothing else, double the size every time rather than increment by one.
As Fred Nurk sugessted in the comments above, I add this as answer:
The variable must not be named close ... now I renamed it and it is working. ... but my vi do not highlight "close" :-)
--edit1:
what I have done now is:
void addInputParamReal(
OCIExtProcContext *ctx
,OCINumber *value
)
{
// do we need more mem?
if (bar1size==0)
{
bar1close = (TA_Real *) malloc(initsize * sizeof(TA_Real));
bar1size=initsize;
}
else if (bar1size<bar1idx || bar1size == 65536)
{
raise_exception(ctx,__LINE__,"addInputParamReal,memory allocation failed");
return;
}
else if (bar1size==bar1idx)
{
bar1close = (TA_Real *) realloc (bar1close, (bar1idx*2) * sizeof(TA_Real));
bar1size = bar1idx*2;
}
//assign value
double dtemp;
OCINumberToDouble(ctx,value,&dtemp);
bar1close[bar1idx++] = (TA_Real) dtemp;
}

Returning local data from functions in C and C++ via pointer

I have argument with my friend. He says that I can return a pointer to local data from a function. This is not what I have learned but I can't find a counterargument for him to prove my knowledge.
Here is illustrated case:
char *name() {
char n[10] = "bodacydo!";
return n;
}
And it's used as:
int main() {
char *n = name();
printf("%s\n", n);
}
He says this is perfectly OK because after a program calls name, it returns a pointer to n, and right after that it just prints it. Nothing else happens in the program meanwhile, because it's single threaded and execution is serial.
I can't find a counter-argument. I would never write code like that, but he's stubborn and says this is completely ok. If I was his boss, I would fire him for being a stubborn idiot, but I can't find a counter argument.
Another example:
int *number() {
int n = 5;
return &n;
}
int main() {
int *a = number();
int b = 9;
int c = *a * b;
printf("%d\n", c);
}
I will send him this link after I get some good answers, so he at least learns something.
Your friend is wrong.
name is returning a pointer to the call stack. Once you invoke printf, there's no telling how that stack will be overwritten before the data at the pointer is accessed. It may work on his compiler and machine, but it won't work on all of them.
Your friend claims that after name returns, "nothing happens except printing it". printf is itself another function call, with who knows how much complexity inside it. A great deal is happening before the data is printed.
Also, code is never finished, it will be amended and added to. Code the "does nothing" now will do something once it's changed, and your closely-reasoned trick will fall apart.
Returning a pointer to local data is a recipe for disaster.
you will get a problem, when you call another function between name() and printf(), which itself uses the stack
char *fun(char *what) {
char res[10];
strncpy(res, what, 9);
return res;
}
main() {
char *r1 = fun("bla");
char *r2 = fun("blubber");
printf("'%s' is bla and '%s' is blubber", r1, r2);
}
As soon as the scope of the function ends i.e after the closing brace } of function, memory allocated(on stack) for all the local variables will be left. So, returning pointer to some memory which is no longer valid invokes undefined behavior.
Also you can say that local variable lifetime is ended when the function finished execution.
Also more details you can read HERE.
My counter-arguments would be:
it's never OK to write code with undefined behavior,
how long before somebody else uses that function in different context,
the language provides facilities to do the same thing legally (and possibly more efficiently)
It's undefined behavior and the value could easily be destroyed before it is actually printed. printf(), which is just a normal function, could use some local variables or call other functions before the string is actually printed. Since these actions use the stack they could easily corrupt the value.
If the code happens to print the correct value depends on the implementation of printf() and how function calls work on the compiler/platform you are using (which parameters/addresses/variables are put where on the stack,...). Even if the code happens to "work" on your machine with certain compiler settings it's far from sure that it will work anywhere else or under slightly different border conditions.
You are correct - n lives on the stack and so could go away as soon as the function returns.
Your friend's code might work only because the memory location that n is pointing to has not been corrupted (yet!).
As the others have already pointed out it is not illegal to do this, but a bad idea because the returned data resides on the non-used part of the stack and may get overridden at any time by other function calls.
Here is a counter-example that crashes on my system if compiled with optimizations turned on:
char * name ()
{
char n[] = "Hello World";
return n;
}
void test (char * arg)
{
// msg and arg will reside roughly at the same memory location.
// so changing msg will change arg as well:
char msg[100];
// this will override whatever arg points to.
strcpy (msg, "Logging: ");
// here we access the overridden data. A bad idea!
strcat (msg, arg);
strcat (msg, "\n");
printf (msg);
}
int main ()
{
char * n = name();
test (n);
return 0;
}
gcc : main.c: In function ‘name’:
main.c:4: warning: function returns address of local variable
Wherever it could been done like that (but it's not sexy code :p) :
char *name()
{
static char n[10] = "bodacydo!";
return n;
}
int main()
{
char *n = name();
printf("%s\n", n);
}
Warning it's not thread safe.
You're right, your friend is wrong. Here's a simple counterexample:
char *n = name();
printf("(%d): %s\n", 1, n);
Returning pointer to local variable is aways wrong, even if it appears to work in some rare situation.
A local (automatic) variable can be allocated either from stack or from registers.
If it is allocated from stack, it will be overwritten as soon as next function call (such as printf) is executed or if an interrupt occurs.
If the variable is allocated from a register, it is not even possible to have a pointer pointing to it.
Even if the application is "single threaded", the interrupts may use the stack. In order to be relatively safe, you should disable the interrupts. But it is not possible to disable the NMI (Non Maskable Interrupt), so you can never be safe.
While it is true that you cannot return pointers to local stack variables declared inside a function, you can however allocate memory inside a function using malloc and then return a pointer to that block. Maybe this is what your friend meant?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* getstr(){
char* ret=malloc(sizeof(char)*15);
strcpy(ret,"Hello World");
return ret;
}
int main(){
char* answer=getstr();
printf("%s\n", answer);
free(answer);
return 0;
}
The way I see it you have three main options because this one is dangerous and utilizes undefined behavior:
replace: char n[10] = "bodacydo!"
with: static char n[10] = "bodacydo!"
This will give undesirable results if you use the same function more than once in row while trying to maintain the values contained therein.
replace:
char n[10] = "bodacydo!"
with:
char *n = new char[10];
*n = "bodacydo!"
With will fix the aforementioned problem, but you will then need to delete the heap memory or start incurring memory leaks.
Or finally:
replace: char n[10] = "bodacydo!";
with: shared_ptr<char> n(new char[10]) = "bodacydo!";
Which relieves you from having to delete the heap memory, but you will then have change the return type and the char *n in main to a shared_prt as well in order to hand off the management of the pointer. If you don't hand it off, the scope of the shared_ptr will end and the value stored in the pointer gets set to NULL.
If we take the code segment u gave....
char *name() {
char n[10] = "bodacydo!";
return n;
}
int main() {
char *n = name();
printf("%s\n", n);
}
Its okay to use that local var in printf() in main 'coz here we are using a string literal which again isn't something local to name().
But now lets look at a slightly different code
class SomeClass {
int *i;
public:
SomeClass() {
i = new int();
*i = 23;
}
~SomeClass() {
delete i;
i = NULL;
}
void print() {
printf("%d", *i);
}
};
SomeClass *name() {
SomeClass s;
return &s;
}
int main() {
SomeClass *n = name();
n->print();
}
In this case when the name() function returns SomeClass destructor would be called and the member var i would have be deallocated and set to NULL.
So when we call print() in main even though since the mem pointed by n isn't overwritten (i am assuming that) the print call will crash when it tried to de-reference a NULL pointer.
So in a way ur code segment will most likely not fail but will most likely fail if the objects deconstructor is doing some resource deinitialization and we are using it afterwards.
Hope it helps

Resources