Why does an error occur when running the program? - c

I have an error and I can't find a method to solve it.I get this error
Exception thrown at 0x504A3E6C (ucrtbased.dll) in
ConsoleApplication3.exe: 0xC0000005: Access violation reading location
0x0047617A. On line 11.
#include "Entities.h"
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
Expense* createExp(int nr_ap, float price, char* type) {
Expense *e = malloc(sizeof(Expense));
e->nr_ap = nr_ap;
e->price = price;
e->type = malloc(sizeof(char)*strlen(type) + 1); #Here is the problem.
strcpy(e->type, type);
return e;
}
void destroy(Expense *e) {
free(e->type);
free(e);
}
int getAp(Expense *e) {
return e->nr_ap;
}
float getPrice(Expense *e) {
return e->price;
}
char* getType(Expense *e) {
return e->type;
}
/*
Create a copy
*/
Expense *copyExp(Expense *e) {
return createExp(e->nr_ap, e->price, e->type);
}
void testCreateExp() {
Expense *e = createExp(10, 120, 'Gaz');
assert(getAp(e) == 10);
assert(getPrice(e) == 12);
assert(getType(e) == "Gaz");
destroy(e);
}
int main() {
testCreateExp();
}

Expense *e = createExp(10, 120, 'Gaz'); Makes no sense. single quote are used for single characters, not C strings.
e.g. char initial = 'G'; char* name = "Gaz";
Try Expense *e = createExp(10, 120, "Gaz");. Most compilers should give you a warning that using a single quote is not right in this context.
Also suspect your asserts are not "as expected" assert(getType(e) == "Gaz"); - shouldn't that be a strcmp() ?

Related

Mors Alphabet Segmentation Fault

My code doesn't adding second node to tree. It gives me SIGSEGV fault when i'm adding the second node.I think its about strcmp function but when i'm trying to understand how it works properly at the very bottom of main func it returns -1 so i've wrote it like this.And most of my variables named Turkish so here are the translations of them to make you understand more easily
dugum=node,kok=root;sol=left;sag=right;anne=mother
// C program to demonstrate insert operation in binary search tree
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct tree {
char *harf;
char *morskodu;
struct tree *left;
struct tree *right;
} agac;
agac *kok = NULL;
void ekle(char *harf, char *morskodu) {
if (kok == NULL) {
kok = (agac *)malloc(sizeof(agac));
kok->harf = harf;
kok->morskodu = morskodu;
kok->left = NULL;
kok->right= NULL;
} else {
agac *yeni = (agac *)malloc(sizeof(agac));
yeni->harf = harf;
yeni->morskodu = morskodu;
yeni->left = NULL;
yeni->right = NULL;
agac *dugum = kok, *anne;
while (dugum != NULL) {
anne = dugum;
if (harf <= dugum->harf)
dugum = dugum->left;
else
dugum = dugum->right;
}
if (harf <= dugum->harf)
anne->left = yeni;
else
anne->right = yeni;
}
}
void dolas(agac *dugum) {
if (dugum != NULL) {
printf(" %s ", dugum->harf);
dolas(dugum->left);
dolas(dugum->right);
}
}
void main() {
ekle("a", "-");
ekle("b", "-.");
dolas(kok);
int x = strcmp("A", "B");
printf("%d", x);
}
You try to dereference a NULL pointer.
while (dugum != NULL) {
anne = dugum;
if (harf <= dugum->harf)
dugum = dugum->sol;
else
dugum = dugum->sag;
}
This loop ends when dugum is NULL.
Directly after you try to access dugum->harf:
if (harf <= dugum->harf)
This leads to undefined behavior.
Also note that this comparisons compare the pointers to string literals, and is therefore also undefined behavior. To compare two C strings you should use strcmp.

Freeing memory gives segmentation fault [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 4 years ago.
Improve this question
I've been trying to work with structures, pointers and memory in C.
I have created this structure
typedef struct {
int id;
char *name;
} Object;
here is constructor
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if(sizeof(o->name)!=sizeof(name))
{
o->name=NULL;
}
else
{
strcpy(o->name, name);
}
}
here is decleration of o1
char tmp_name[] = "Hello 1";
Object o1;
object_ctor(&o1, 1, tmp_name);
here is destructor
void object_dtor(Object *o)
{
if(o->name != NULL)
{
free(o->name);
o->name = NULL;
}
}
printing object
void print_object(Object *o)
{
printf("ID: %d, NAME: %s\n", o->id, o->name);
}
calling copy
Object copy;
print_object(object_cpy(&copy, &o1));
and I´m trying create a copy of one structure to another (I have already constructed them).
Object *object_cpy(Object *dst, Object *src)
{
if(src!=NULL)
{
const size_t len_str=strlen(src->name)+1;
dst->name = malloc(10000000);
dst->id = src->id;
strncpy (dst->name, src->name,len_str);
}
if (strcmp(dst->name,src->name)!=0)
{
dst->name = NULL;
}
return dst;
}
But then when I'm trying to free both copy and original src I get a segmentation fault. I've been trying to run it through gdb and it said that I'm freeing same memory twice so I assume that the code for copying is wrong, but I don't know where.
And here is code that gives me segmentation fault
printf("\nCOPY EMPTY\n");
object_dtor(&copy);
o1.id = -1;
free(o1.name);
o1.name = NULL;
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
I´m including these libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
I'm using the std=c99 flag for to compile.
There is at least a problem here:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(sizeof(name));
if (sizeof(o->name) != sizeof(name))
{
o->name = NULL;
}
else
{
strcpy(o->name, name);
}
}
sizeof(name) is not the length of the string pointed by name. You need strlen(name) + 1 (+1 for the NUL terminator).
And your test if (sizeof(o->name) != sizeof(name)) is pointless, and I'm not sure what you're trying to achieve here.
You probably want this:
void object_ctor(Object *o, int id, char *name)
{
o->id = id;
o->name = malloc(strlen(name) + 1);
if (o->name != NULL)
strcpy(o->name, name);
}
There are similar problems in object_cpy:
pointless use of strncpy
pointless allocation of a 10Mb buffer
pointless test strcmp(dst->name, src->name)
You probably want this:
Object *object_cpy(Object *dst, Object *src)
{
if (src != NULL)
{
const size_t len_str = strlen(src->name) + 1;
dst->name = malloc(len_str);
if (dst->name != NULL)
{
dst->id = src->id;
strcpy(dst->name, src->name);
}
}
return dst;
}
With these corrections following code works fine:
int main()
{
char tmp_name[] = "Hello 1";
Object o1, copy;
object_ctor(&o1, 1, tmp_name);
object_cpy(&copy, &o1);
print_object(&copy);
print_object(&o1);
object_dtor(&o1);
object_dtor(&copy);
}
Event if this is not directly an answer to your problem, I'll give you how I organize my code in order to avoid memory problem like yours.
First, it all resolve around a structure.
To each structure, if needed, I do a "Constructor" and a "Destructor".
The purpose of the constructor is simply to set the structure in a coherent state. It can't never fail (implying that any code that could fail, like malloc, should not be in the constructor).
The purpose of the destructor is to clean the structure.
One little trick that I like to use is to put the constructor in a macro, allowing me to do something like 'Object var = OBJET_CONSTRUCTOR'.
Of course, it's not alway possible, it's up to you to be carreful.
For your code, it could be :
typedef struct {
int id;
char *name;
} Object;
#define OBJECT_CONSTRUCTOR {.id = -1,\ \\ Assuming -1 is relevant in your case, like an error code or a bad id value. Otherwise, it's useless.
.name = NULL}
void Object_Constructor(Object *self)
{
Object clean = OBJECT_CONSTRUCTOR;
*self = clean;
}
void Object_Destructor(Object *self)
{
free(self->name);
}
Here we go.
How to use it is simple : You always begin by the constructor, and you alway end by the destructor. That's why it's useless to set the char pointer "name" to NULL in the destructor, because it should not be used after by any other function that the constructor.
Now, you can have "initialisation" function. You can do a plain initialisation (it is your constructor function), or a copy initialisation, etc etc
Just keep in mind that the structure have been called into the constructor. If not, it's the developer fault and you do not have to take that in count.
A behavior that can be nice is, in case of error, to not modify the structure.
Either the structure is entierly modified in succes, or not at all.
For complex structure that can fail at many point, you can do that by "swapping" the result at the end.
void Object_Swap(Object *first, Object *second)
{
Object tmp = OBJECT_CONSTRUCTOR;
tmp = *fisrt;
*first = *second;
*second = tmp;
}
bool Object_InitByPlainList(Object *self, int id, consr char *name)
{
Object newly = OBJECT_CONSTRUCTOR;
bool returnFunction = false;
newly.id = id;
if (!(newly.name = strdup(name))) {
printf("error : %s : strdup(name) : name='%s', errno='%s'.\n", __func__, name, strerror(errno));
goto END_FUNCTION;
}
// Success !
Object_Swap(self, &newly);
returnFunction = true;
/* GOTO */END_FUNCTION:
Object_Destructor(&newly);
return (returnFunction);
}
It may be seem overcomplicated at the first glance, but that organization allow you to add more futur step "that can fail" cleanly.
Now, you can even do something this simply :
bool Object_InitByCopy(Object *dst, Object *src)
{
return (Object_InitByPlainList(dst, src->id, src->name));
}
All you have to do is to say in the documentation :
The first function to be called have to be "Object_Constructor"
After the "Object_Constructor", only the "Object_Init*" function can be called.
The last function to be call have to be "Object_Destructor"
That's all. You can add any "Object_*" function that you whant, like :
void Object_Print(const Object *self)
{
printf("ID: %d, NAME: %s\n", self->id, self->name);
}
Hope this organization will solve your memory problem.
An example :
int main(void)
{
Object test = OBJECT_CONSTRUCTOR;
Object copy = OBJECT_CONSTRUCTOR;
if (!Object_InitByPlainList(&test, 1, "Hello World !")) {
// The function itself has logged why it has fail, so no need to add error printf here
return (1);
}
Object_Print(&test);
if (!Object_Copy(&copy, &test)) {
return (1);
}
Object_Destructor(&test);
Object_Destructor(&copy);
return (0);
}

How do you use a typedef struct for a FIFO?

I just started programming in C for school. I am being asked to do a program that uses a FIFO struct to resolve math problems. I got the folowing code on the internet for a FIFO, I just don't know how to use it. I tried a lot of things and I can't find anything useful on the internet or maybe that I just don't know the right thing to research but could you please help me? Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct pile
{
int donnee;
struct pile *precedent;
} Pile;
void pile_push(Pile **p_pile, int donnee)
{
Pile *p_nouveau = malloc(sizeof *p_nouveau);
if (p_nouveau != NULL)
{
p_nouveau->donnee = donnee;
p_nouveau->precedent = *p_pile;
*p_pile = p_nouveau;
}
}
int pile_pop(Pile **p_pile)
{
int ret = -1;
if (p_pile != NULL)
{
Pile *temporaire = (*p_pile)->precedent;
ret = (*p_pile)->donnee;
free(*p_pile), *p_pile = NULL;
*p_pile = temporaire;
}
return ret;
}
void pile_clear(Pile **p_pile)
{
while (*p_pile != NULL)
{
pile_pop(p_pile);
}
}
I tried doing this:
int main()
{
int return_val;
Pile pile;
pile_push(Pile, 5);
return_val = pile_pop(Pile);
printf(return_val);
}
and got this error:
expected expression before 'Pile'
too few arguments to function 'pile_push'
You have mixed up Pile and pile which is the issue with the first warning. The functions expect a pointer to a pointer to a Pile. That is: They update the value of a pointer, so they need to be passed a reference to a pointer. Your use of printf is also wrong.
int main()
{
int return_val;
Pile *pile = NULL;
pile_push(&pile,5);
return_val = pile_pop(&pile);
printf("return_val is: %d\n",return_val);
}

Error in CloudPebble, "ld returned 1 exit status"

So, I'm trying to make a Pebble app that generates a random string when you press a button. I'm pretty sure I have the Pebble code right, but I'm not sure what to do with this error:
/sdk2/[long stuff here]/ In function `_sbrk_r':
/home/[more long stuff]: undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Waf: Leaving directory `/tmp/tmpX94xY7/build'
Build failed
And here's my code:
#include <pebble.h>
#include <stdlib.h>
#include <stdio.h>
Window *window;
TextLayer *text_layer;
char* one[] = {"string1", "stringone", "stringuno"};
char* two[] = {"string2", "stringtwo", "stringdos"};
char* three[] = {"string3", "stringthree", "stringtres"};
char* four[] = {"string4", "stringfour", "stringcuatro"};
int length1 = sizeof(one)/sizeof(*one);
int length2 = sizeof(two)/sizeof(*two);
int length3 = sizeof(three)/sizeof(*three);
int length4 = sizeof(four)/sizeof(*four);
char* gen()
{
char out[256];
sprintf(out, "%s, and then %s %s %s.", one[rand() % length1], two[rand() % length2], three[rand() % length3], four[rand() % length4]);
char* result = malloc(strlen(out) + 1);
strcpy(result, out);
return result;
}
static void select_click_handler(ClickRecognizerRef recognizer, void *context)
{
char* stringGen = gen();
text_layer_set_text(text_layer, stringGen);
free(stringGen);
}
static void click_config_provider(void *context)
{
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
window_single_click_subscribe(BUTTON_ID_UP, select_click_handler);
window_single_click_subscribe(BUTTON_ID_DOWN, select_click_handler);
}
static void window_load(Window *window)
{
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
text_layer = text_layer_create((GRect) { .origin = { 0, 72 }, .size = { bounds.size.w, bounds.size.h } });
text_layer_set_text(text_layer, "Press >>>");
text_layer_set_text_alignment(text_layer, GTextAlignmentCenter);
layer_add_child(window_layer, text_layer_get_layer(text_layer));
}
static void window_unload(Window *window)
{
text_layer_destroy(text_layer);
}
void handle_init(void)
{
window = window_create();
window_set_click_config_provider(window, click_config_provider);
window_set_window_handlers(window, (WindowHandlers) {
.load = window_load,
.unload = window_unload,
});
const bool animated = true;
window_stack_push(window, animated);
}
void handle_deinit(void)
{
text_layer_destroy(text_layer);
window_destroy(window);
}
int main(void)
{
handle_init();
app_event_loop();
handle_deinit();
}
I can't figure out why I'm getting that error. It's a simple application, I just have these little tweaks.
Thank you in advance for your help!
According to this (old) FAQ, that error happens when you try to use a C standard library function that hasn't been implemented in the SDK. If you look in the API reference, snprintf is available, but not sprintf. You can replace your call to sprintf in gen with something like
snprintf(out, 256, "%s, and then %s %s %s.", one[rand() % length1], two[rand() % length2], three[rand() % length3], four[rand() % length4]);
I just tried this out and it builds fine.
(As an aside, it may be a better a idea to declare out a global static buffer and just write over it each time, instead of constantly dynamically allocating memory.)

stack of coins, push function (C)

I got a stack of coins, which are made this way:
#define MAX_PAIS 20
typedef int VALUE;
typedef struct {
VALUE value;
char country [MAX_PAIS];
} COIN;
and
#define MAXSTACK 100
typedef struct {
int top;
ELESTACK item [MAXSTACK];
} STACK;
to push a coin into the stack, I do:
STATUS push(STACK *stc, const ELESTACK *ele) {
//stuff
stc->top++;
retorno = copyEleStack(stc->item[stc->top], ele);
//stuff
}
the important thing is the copyElestack thing, my ide gives me an error, it says this function needs the first argument to be struct elestack * but is elestack... the mentioned function do that:
ELESTACK *copyEleStack(ELESTACK *dst, const ELESTACK *src) {
int retorno;
retorno = copyCoin(dst, src);
if (retorno == ERROR) {
return NULL;
}
}
and copycoin:
STATUS copyCoin(COIN * pDest, const COIN * pOrigin) {
pDest->value = pOrigin->value;
strcpy(pDest->country, pOrigin->country);
if (pDest->value != 0 && pDest->country != NULL) {
return OK;
}
return ERROR;
I think this might be something related to the pointers, but I'm not seeing it right now, any help would be nice
Your compiler is telling you the right thing. copyEleStack takes an ELESTACK*, but you are passing it an ELESTACK value. Try &stc->item[stc->top] or alternately (stc->item+stc->top)

Resources