Reputation:
I'm trying to do a linked list of recettes (recipes in French)
Here is my code:
/*
* Copyright 2015 Robeen Simeon
* http://robeen.ca
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
typedef struct Recette Recette;
struct Recette
{
char *nom;
Recette *suivant;
};
typedef struct Categorie Categorie;
struct Categorie
{
char* nom;
Categorie *suivant;
};
Recette* addRecette(Recette *precedent, char* nomRecette);
void printRecette(Recette* recette);
void printRecettes(Recette* premiereRecette);
/* MAIN */
int main (int argc, char **argv)
{
char *nom = malloc(256);
nom = "poulet";
Recette *premiereRecette;
premiereRecette = addRecette(NULL, nom);
char *nom2 = malloc(128);
strcpy(nom2, "boeuf");
Recette *deuxiemeRecette;
deuxiemeRecette = addRecette(premiereRecette, nom2);
printRecettes(premiereRecette);
}
/* FONCTIONS */
Recette* addRecette(Recette *precedent, char* nomRecette)
{
Recette *recette = malloc(sizeof(*recette));
recette->nom = nomRecette;
if (precedent != NULL) {
precedent->suivant = recette;
}
else
{
recette->suivant = NULL;
}
return recette;
}
void printRecette(Recette* recette)
{
printf("Cette recette est : %s\n", recette->nom);
if(recette->suivant != NULL)
{
printf("Sa recette suivante est : %s\n", recette->suivant->nom );
}
else
{
printf("Pas de suivant\n");
}
}
void printRecettes(Recette* premiereRecette)
{
Recette *recette = premiereRecette;
while (premiereRecette->suivant != NULL) {
printRecette(recette);
recette = recette->suivant;
}
}
Here is in an image the error [EXC_BAD_ACCESS(code=1, address= 0x0)] i'm getting on line 81
.
Sometimes it's [EXC_BAD_ACCESS(code=EXC_l386_GPFLT)] on line 84
though.
The program still gives the right results too.
Upvotes: 1
Views: 309
Reputation: 121649
I believe your loop should check "recette", not "premiereRecette":
void printRecettes(Recette* premiereRecette)
{
Recette *recette = premiereRecette;
/* while (premiereRecette->suivant != NULL) { // WRONG! */
while (recette != NULL) { /* Better. Note that "printRecette()" checks
for "recette->suivant == NULL" */
printRecette(recette);
recette = recette->suivant;
}
}
ALSO:
You can use strdup combine these two lines:
char *nom2 = malloc(128);
strcpy(nom2, "boeuf");
into:
char *nom2 = strdup("boef");
This is an error:
char *nom = malloc(256);
nom = "poulet"; /* WRONG!
Use "strcpy()" or "strdup()".
Or char *nom = "poulet"; */
And don't forget to "free()" any strings you've "malloc'ed"!
Upvotes: 0
Reputation: 36401
This is not a bug in C on XCode. The error message is effectively cryptic, but your title a slightly misleading. exc_bad_access
(an XCode tool message) is generally due to a try to access a forbidden memory address. If you execute your code on a terminal, you would have Segmentation violation
(a well-known message for programmers).
Two bugs, in the while loop your test is the wrong one, and in the add function you didn't initialize the structure correctly:
void printRecettes(Recette* premiereRecette) {
Recette *recette = premiereRecette;
while (recette->suivant != NULL) { // loop on recette pointer...
printRecette(recette);
recette = recette->suivant;
}
}
Recette* addRecette(Recette *precedent, char* nomRecette) {
Recette *recette = malloc(sizeof(*recette));
recette->nom = nomRecette;
recette->suivant = NULL; // initialize all fields
if (precedent != NULL) {
precedent->suivant = recette;
}
return recette;
}
You also allocated chars for the first recipe name, that you don't use; this is a memory leak. Either forget the allocation or use strcpy
as for the second recipe.
Upvotes: 2