Violation of access with pointers and scanf - c

The following code is supposed to insert the name of a good, whether it's getting stored or sent away (with just a single letter, like i for in or o for out) and in conclusion how much of that item is getting moved.
Then the program should end whenever I write the END phrase.
Problem is, I am finding a violation of access while trying to save the number of items, and cannot seem to find where I am doing something wrong.
#define MAX 20
#define END "FINE"
typedef struct type_struct {
char name[MAX];
char move[2];
int quantity;
struct type_struct* next;
}type;
void insert(type* p) {
type* aux;
aux = p;
while (aux != NULL)
aux = aux->next;
aux = malloc(sizeof(type));
printf("name of good: ");
scanf("%s", aux->name);
getchar();
printf("in or out?: ");
scanf("%c", aux->move);
printf("quantity: ");
scanf("%d", aux->quantity);
printf("\n");
}
int main(void) {
type* phrase=NULL;
char fine[5];
strcpy(fine, END);
do {
insert(phrase);
} while ((strcmp(phrase, fine) == 0));
}
It should be very simple, however, I am clueless and hope you might give me a hand

Related

comparing strings in a structure pointer in C

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
struct person {
char user[50];
char password[50];
int amount;
};
int i=0;
int h=0;
int *n=&h;
struct person *p = NULL;
void adduser();
int main()
{
int x;
printf("Welcome to the bank\n");
printf("what would you like to do\n");
printf("type 1 to add a user\n");
printf("type 2 to add to balance\n");
printf("type 3 to take from balance\n");
printf("type 4 to check from balance\n");
scanf("%d%*c",&x);
if(x==1){
adduser();
}
else if (x == 2){
printf("2");
}
else if (x == 3){
printf("3");
}
else if (x == 4){
printf("4");
}
else{
main();
}
}
void adduser(){
struct person *temp = realloc(p, *n * sizeof(struct person));
if (temp != NULL)
p = temp;
printf("n=%d\n",*n-1);
printf("enter your new username\n");
scanf("%s",&(p+*n)->user);
int o=*n-1;
for (i;i<=o;i++)
{
if(strcmp((p+*n)->user,(p+i)->user) == 0)
{
printf("user already exists");
adduser();
}
}
printf("enter your new password\n");
scanf("%s",(p+*n)->password);
*n+=1;
main();
}
hello I'm a beginner with C I'm trying to see i have string the user input similar to one in my structure using this code.
for (i;i<=o;i++)
{
if(strcmp((p+*n)->user,(p+i)->user) == 0)
{
printf("user already exists");
adduser();
}
}
my code is supposed ask the user to enter their new user(at least what i posted) and checks if a similar user exists but my loop gets ignored i don't know what to do with it . i feel like my problem lies elsewhere but i cant figure it out. Also i might have done fundamental mistakes because I'm very new to structures and pointers.
i tried searching online for solutions but i couldn't find a similar situation.
This code is clearly in error:
struct person *temp = realloc(p, *n * sizeof(struct person));
since we're almost immediately going to do:
scanf("%s",&(p+*n)->user);
this really needs to read
struct person *temp = realloc(p, (*n + 1) * sizeof(struct person));
In addition,
for (i;i<=o;i++)
is clearly wrong and should be
for (i=0;i<=o;i++)
and as dxiv points out, i really should be declared in this for loop rather than as a global.
Incidentally, are you having trouble with loops? I don't see that recursive call of main() much. It's really clever, but this code works well only if compiled with optimizations on (which in turn is harder to debug). I'd advise replacing
else{
main();
}
and the other calls to main() with an infinite loop around all of main() (which eventually will have a loop exit condition or a conditional break; statement on the input ladder.

how to use a string in struct in linked list?

In my code I have 2 structs named villa and apartment. They have members of type char*. When in my void record I get other parts of the structs like villa1.price (which is float) from user,It works ,but when it comes to the char*,I cannot read strings using scanf("%s",&villa1.city) and so I used another array of chars named v1 to get info from users and then assign it to villa1.city using villa1.city=a1.
This worked for the first time, but I want to make a linked list. The first time I send villa1.city to insertFirstVilla to add this to linked list it works, but when I add second node ,the villa1.city in first node is lost and it keeps happening every time I add a new node.
How can I get data from user like villa1.price or if it is not possible how to copy it in way that data remains safe when I add second node to my list.
I post a part of my code for villa, but the code is the same for apartment.
struct villa
{
float built;
float garden;
float price;
int floors;
char* city;
char* ST;
char* alley;
char* postal_code;
}villa1;
struct nodev
{
villa info;
nodev* next;
}*headv = NULL;
void insertFirstvilla(float built, float garden,float price,int floor, char*city) {
nodev* link = (nodev*)malloc(sizeof(nodev));
link->info.built = built;
link->info.garden = garden;
link->info.price = price;
link->info.floors = floor;
link->info.city = city;
link->next = headv;
headv = link;
}
void record()
{
char a;
printf("is the building apartment? (y/n):");
scanf("%c", &a);
char a1[100];
char v1[100];
if (a == 'y')
{
/* printf("enter apartment features:");
printf("\nenter built area:");
scanf("%f", &apart.built);
printf("\nenter basic price:");
scanf("%f", &apart.price);
printf("\nenter floors number:");
scanf("%d", &apart.floor_no);
printf("\ndoes apartment have elavator(if there is no elavotor enter zero else enter one):");
scanf("%d", &apart.elevator);
printf("\nenter city:");
scanf("%s", &a1);
apart.city = a1;
insertFirstapartment(apart.built, apart.price, apart.floor_no, apart.elevator,apart.city);
writetofilea(apart.built, apart.price, apart.floor_no, apart.elevator, apart.city);*/
}
else if (a == 'n')
{
printf("enter villa features:");
printf("\nenter built area:");
scanf("%f", &villa1.built);
printf("\nenter garden area:");
scanf("%f", &villa1.garden);
printf("\nenter basic price:");
scanf("%f", &villa1.price);
printf("\nenter floors number:");
scanf("%d", &villa1.floors);
printf("\nenter city:");
scanf("%s", &v1);
apart.city = v1;
insertFirstvilla(villa1.built, villa1.garden, villa1.price, villa1.floors, villa1.city);
writetofilev(villa1.built, villa1.garden, villa1.price, villa1.floors, villa1.city);
}
getchar();
}
int main()
{
int t = 0;
while (t<4)
{
record();
t++;
}
}
As an example reading the city:
char a1[100];
scanf("%99s", a1); // an array will be passed as an address, so no need for &
apart.city = malloc(strlen(a1)+1); // ask for memory
strcpy(apart.city, a1); // copy it
or use strdup, which does this for you:
char a1[100];
scanf("%99s", a1); // an array will be passed as an address, so no need for &
apart.city= strdup(a1); // get memory and copy it
The basic problem is deep copying versus shallow copying.
struct villa
{
int floors;
char* city;
};
villa V1, V2;
char buffer[10];
strcpy(buffer, "Venice");
V1.city = buffer; /* This copies nothing. V1.city now points to buffer. */
V2 = V1; /* This is a shallow copy. V2.city now points to buffer. */
strcpy(buffer, "Moscow");
printf("%s\n", V2.city); /* prints Moscow */
Do you see the problem? If you want each villa to have a buffer of its own, you must write code to allocate and manage that memory, and if you want the copies to be deep copies, you must write an assignment operator.

Getting stuck in Dictionary Project in C

I prefer to create a Dictionary object and add 3 words to it.
My program has no compilation error but gets a run time error in the second for loop, is the problem in addNewWord function? Do I need pass a pointer to the DictionaryWord object ?
Please help me.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
char* name;
char* mean;
} Words;
typedef struct{
Words* word;
int size;
} Dictionary;
Dictionary createNewDictionary();
Words createNewWord();
void addNewWord(Words newword, Dictionary dic);
Dictionary createNewDictionary(){
Dictionary dic;
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
return dic;
}
Words createNewWord(){
Words newword;
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", newword.name);
fflush(stdin);
printf("\nEnter meaning: ");
scanf("%[^\n]", newword.mean);
return newword;
}
void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
}
int main(){
Dictionary d = createNewDictionary();
for (int i=0;i<3;i++){
addNewWord(createNewWord(), d);
}
return 0;
}
There are lots of problem with your code:
Given the longest word in English is around 30 characters, this size allocation is realistic for the word, but not for the defintion:
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
This makes little obvious sense:
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
you called malloc() on zero! You're only spared by your later realloc(). Even if intentional, it really deserves a comment.
This doesn't really work as fflush() is for output streams:
fflush(stdin);
see: How to clear input buffer in C? And whatever fix you use has to apply to both scanf() calls, not just one!
Per #Jarvis, this doesn't work:
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
as you didn't allocate any space for name and mean in dic so you're copying into random memory.
Per #Jarvis, doesn't work:
void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
You're passing dic by value so inside addnewWord() you've a copy of dic so the original dic's size will be the same as it was before the call!
Memory leak:
addNewWord(createNewWord(), d);
you dropped your handle onto what createNewWord() returned so you can never free the memory it malloc()'d
You malloc() memory but provide no means to eventually free it.
Passing and returning structs by value is a disaster in a situation like this, as the data keeps getting copied. At the least it's inefficient, at worst its buggy like the size issue above. Rather than risk it, pretend they can only be passed and returned by pointer and you'll be playing it safe and get a better result.
Below is a rework of your code (in C) with fixes, style tweaks and an attempt at a consistent terminology. It also provides some minimal test code and the ability to free your data:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LENGTH 30
#define MAX_DEFINITION_LENGTH 1024
typedef struct entry {
char *word;
char *definition;
} Entry;
typedef struct dictionary {
Entry *entries;
int num_entries, max_entries;
} Dictionary;
Dictionary *createNewDictionary() {
Dictionary *dictionary = malloc(sizeof(*dictionary));
dictionary->num_entries = 0;
dictionary->max_entries = 1;
dictionary->entries = calloc(dictionary->max_entries, sizeof(*dictionary->entries));
return dictionary;
}
void freeEntry(Entry *entry) {
free(entry->word);
free(entry->definition);
free(entry);
}
void freeDictionary(Dictionary *dictionary) {
for (--dictionary->num_entries; dictionary->num_entries >= 0; --dictionary->num_entries) {
// we can't call freeWord() here -- why.
free(dictionary->entries[dictionary->num_entries].word);
free(dictionary->entries[dictionary->num_entries].definition);
}
free(dictionary->entries);
free(dictionary);
}
void purgeInput() {
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
Entry *requestNewEntry() {
Entry *entry = malloc(sizeof(*entry));
entry->word = malloc(MAX_WORD_LENGTH);
entry->definition = malloc(MAX_DEFINITION_LENGTH);
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", entry->word);
purgeInput();
printf("\nEnter definition: ");
scanf("%[^\n]", entry->definition);
purgeInput();
return entry;
}
void addNewEntry(Entry *entry, Dictionary *dictionary) {
if (dictionary->num_entries == dictionary->max_entries) {
dictionary->max_entries *= 2;
dictionary->entries = realloc(dictionary->entries, dictionary->max_entries * sizeof(*dictionary->entries));
// check if realloc returns NULL and if so, handle the error.
}
dictionary->entries[dictionary->num_entries].word = strdup(entry->word);
dictionary->entries[dictionary->num_entries].definition = strdup(entry->definition);
dictionary->num_entries++;
}
int main() {
Dictionary *d = createNewDictionary();
for (int i = 0; i < 3; i++) {
Entry *e = requestNewEntry();
addNewEntry(e, d);
freeEntry(e);
}
printf("\nRead: ");
for (int i = 0; i < d->num_entries; i++) {
printf("%s (%lu chars) ", d->entries[i].word, strlen(d->entries[i].definition));
}
printf("\n");
freeDictionary(d);
return 0;
}
CREATING A PUN DICTIONARY
> ./a.out
============================
Enter word: silkworm
Enter definition: Two silkworms had a race but ended up in a tie.
============================
Enter word: horse
Enter definition: A horse is a stable animal.
============================
Enter word: termite
Enter definition: A termite walks into a pub and asks, "Is the bar tender here?"
Read: silkworm (47 chars) horse (27 chars) termite (62 chars)
>
I see what's wrong with your code. First of all, you need to pass your Dictionary object by pointer to the function, addNewWord, and in the function addNewWord, you again need to allocate memory to each of the char* fields, name and mean, of the dic object. Here is the corrected code :
void addNewWord(Words newword, Dictionary *dic){
dic->size++;
dic->word = (Words*)realloc(dic->word, dic->size*sizeof(Words));
dic->word[dic->size-1].name = (char*)malloc(30*sizeof(char)); //added
dic->word[dic->size-1].mean = (char*)malloc(30*sizeof(char)); //added
strcpy(dic->word[dic->size-1].name, newword.name);
strcpy(dic->word[dic->size-1].mean, newword.mean);
}
Pass the dictionary's address as :
addNewWord(createNewWord(), &d);
and change the definition as well as prototype of the function as well :
void addNewWord(Words newword, Dictionary *dic)
Find the complete code here : http://pastebin.com/ZN69hevj

Adding records with pointers to arrays

I have to create a program which adds records to a simple phone book. The code is below, but it doesn't work - function ends and then it stucks on declaring struct record x and doesn't want to display my added record - the program breaks down. When I put this part of code on the end of the function (but instead of "struct record x = array[0];" I put "struct record x = (*array)[0]") it works - record is printed. So I guess the problem is something about pointers, but I'm struggling and I really couldn't find out what's wrong. I remember that few weeks ago I created a program which was very similar but it was adding a new record to an array of integers, with fixed values and it was working well, so maybe there's something with structures that I don't know about. Thanks for any help!
I know the program isn't done yet and I know that I didn't make any action for temp_array == NULL, it'll be done after I found out what's going on.
struct record {
char f_name[SIZE];
char name[SIZE];
long int phone;
};
int add_record(struct record** array, int n)
{
struct record* temp_array = malloc((n+1) * sizeof(struct record));
if (temp_array == NULL)
{
free(temp_array);
return -1;
}
int i;
for (i=0; i < n; i++)
{
temp_array[i] = (*array)[i];
}
struct record new_record;
printf("\nAplly data.");
printf("\nFirst name: "); /*fgets(new_record.f_name, SIZE, stdin);*/ scanf("%s", &new_record.f_name);
printf("Surname: "); /*fgets(new_record.name, SIZE, stdin);*/ scanf("%s", &new_record.name);
printf("Phone number: "); scanf("%d", &new_record.phone);
temp_array[n] = new_record;
free (*array);
*array = temp_array;
//struct record x = (*array)[0];
//puts(x.f_name); puts(x.name); printf("%d", x.phone);
return 0;
}
main()
{
struct record* array; int n = 0;
int choice;
printf("\n1. Add record\n2. Delete record\n3. Find record\n0. Exit\n\nChoose action: ");
scanf("%d", &choice);
switch(choice) {
case 0: printf("\nKsiazka zostala zamknieta.\n"); return;
case 1: add_record(&array, n); n++; break;
case 2: return;
case 3: return;
default: printf("Wrong choice.\n\n"); return;
}
struct record x = array[0];
puts(x.f_name); puts(x.name); printf("%d", x.phone);
}
struct record* array=NULL;, and use %ld for long int – BLUEPIXY

Why does strcpy read extra characters?

I just have a question(s) about making a binary tree, as this code doesn't work, it places nodes where they shouldn't go, and although it never crashes its leaking memory like a busted pipe. The idea was a simple guessing game where it simply tries to guess what you are thinking about, and when it gets it wrong you enter a question and answer to help it learn. Relevant code:
I guess my primary problem is char *guess will sometimes store only fragments of the original string passed to getnew(). The next would be the logic in traverse(), as it will jump to the "no" condition regardless of user input.
struct binary {
unsigned long ID;
char *guess;
char isAns;
struct binary *yes;
struct binary *no;
};
typedef struct binary Node;
void traverse(Node **top)
{
if(*top)
{
char ans[128] = "ok";
char ans2[128] = "ok";
if((*top)->isAns=='y')
{
fprintf(stdout,"Is it %s (y/n)? ",(*top)->guess);
}
else
{
fprintf(stdout,"%s (y/n)? ",(*top)->guess);
}
while(!fgets(ans,128,stdin));
if((*top)->isAns=='y')
{
if(ans=="y")
{
printf("Successful string of guesses!\n");
}
else
{
printf("Enter another question to figure out the difference: ");
while(!fgets(ans,128,stdin));
Node *q=getnew(ans,'n');
printf("Enter the right answer: ");
while(!fgets(ans2,128,stdin));
push1(top,q,'n');
(*top)->yes = getnew(ans2,'y');
}
}
else
{
if(ans=="y")
{
if((*top)->yes)
{
traverse(&(*top)->yes);
}
else
{
printf("Null node for top->yes\n");
printf("Enter an answer: ");
while(!fgets(ans,128,stdin));
(*top)->yes=getnew(ans,'y');
}
}
else
{
if((*top)->no)
{
traverse(&(*top)->no);
}
else
{
printf("Null node for top->no\n");
printf("Enter an answer: ");
while(!fgets(ans,128,stdin));
(*top)->no=getnew(ans,'y');
}
}
}
}
else
{
char ques[128] = "ok";
char ans[128] = "ok";
printf("Node is null\n");
printf("Put in a question and answer to yes condition\n");
printf("Enter question: ");
while(!fgets(ques,128,stdin));
printf("Enter answer for yes condition: ");
while(!fgets(ans,128,stdin));
(*top) = getnew(ques,'n');
(*top)->yes=getnew(ans,'y');
}
printf("\n\n");
}
Node * getnew(char *msg, char isAns)
{
Node *nnew = malloc(sizeof(Node));
nnew->ID=clock();
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
nnew->isAns=isAns;
nnew->yes=0;
nnew->no=0;
return nnew;
}
I appreciate any help.
nnew->guess=malloc(sizeof(msg)); only allocates enough memory for a pointer.
Instead of:
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
use:
nnew->guess=strdup(msg);
You probably want to use strdup
C strings are char * pointers, therefore `sizeof(msg) == sizeof(char*) == 8 or 4". Not what you want.
nnew->guess=malloc(sizeof(msg));
strcpy(nnew->guess,msg);
Should be
nnew->guess = strdup(msg);
Or
nnew->guess=malloc(strlen(msg) + 1);
strcpy(nnew->guess,msg + 1);
The +1 is for the nul termintor (assuming you want it).
I see where guess is malloced but I don't see where it's freed. That would definitely cause memory leaks.
as a side note, I've just spun up a quick program to check into the
nnew->guess=malloc(sizeof(msg));
it looks like this
char str[10] = "string";
printf("%d", sizeof(str));
and surprisingly, it printed 10,
but that method of allocation still makes me uneasy.

Resources