Unexpected breakpoint trying to print C string from struct - c

So I am having two problems with this piece of code. The first problem when I'm following break points through it and I'm trying to copy the array to the struct fields, it is saying Error reading character string. And the second problem I am having is with the output "printMovieInfo function it is not printing out my list and it is causing an "unexpected breakpoint"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#pragma warning(disable : 4996)
#pragma warning(disable : 6387)
typedef struct {
char* g;
char* t;
}MovieInfo;
#define kTenItemsEntered 10
#define kCharacterString 30
//prototypes
void eliminateEndOfLine(char* buffer);
void getMovieInfo(MovieInfo* ptr, char title[], char genre[]);
void printMovieInfo(MovieInfo list[]);
int main() {
MovieInfo newMovieInfo[kTenItemsEntered];
char title[kCharacterString];
char genre[kCharacterString];
printf("Enter 10 Title of Movie and 10 Genres\n");
for (int i = 1; i <= kTenItemsEntered; i++) {
printf("%d:\n", i);
printf("Title: ");
fgets(title, kCharacterString,stdin);
eliminateEndOfLine(title);
printf("Genre: ");
fgets(genre, kCharacterString, stdin);
eliminateEndOfLine(genre);
getMovieInfo(newMovieInfo, title, genre);
}
printMovieInfo(newMovieInfo);
return 0;
}
void getMovieInfo(MovieInfo* ptr, char title[], char genre[]) {
ptr->t = (char*)malloc(strlen(title) + 1);
if (ptr->t == NULL) {
printf("Error allocating the title in the struct\n");
}
ptr->g = (char*)malloc(strlen(genre) + 1);
if (ptr->g == NULL) {
printf("Error allocating the genre in the struct\n");
}
strcpy(ptr->t, title);
strcpy(ptr->g, genre);
}
void printMovieInfo(MovieInfo list[]) {
printf("%-35s %-35s\n", "Title", "Genre");
for (int i = 0; i < kTenItemsEntered; i++) {
printf("%-35s %-35s\n", list[i].t, list[i].g);
}
}
//This is the end of new line function from examples
void eliminateEndOfLine(char* buffer)
{
char* target = strchr(buffer, '\n');
if (target != NULL)
{
*target = '\0';
}
}
Output
The output does not print

I'm guessing you're actually compiling in C++, otherwise this wouldn't compile as you need to use struct MovieInfo, not MovieInfo in C. You can fix that by doing:
typedef struct MovieInfo {
char* g;
char* t;
} MovieInfo;
In main your newMovieInfo is an array of MovieInfo structs. When you call getMovieInfo(newMovieInfo, title, genre);, you're actually passing a pointer to the first element of the array to the function (the array 'decays' into a pointer to the first element). What you should do instead is pass a pointer to the element you actually want to fill in. Array indices start at 0, not 1, so you need to fix your loop as well:
// previously: for (int i = 1; i <= kTenItemsEntered; i++) {
for (int i = 0; i < kTenItemsEntered; i++) {
...
// previously: getMovieInfo(newMovieInfo, title, genre);
getMovieInfo(&newMovieInfo[i], title, genre);
}
Then in getMovieInfo, since you already have a valid pointer to the struct, you don't need to allocate space for a new one:
void getMovieInfo(MovieInfo* ptr, char title[], char genre[]) {
// removed:
// ptr = (MovieInfo*)malloc(sizeof(MovieInfo));
// if (ptr == NULL) {
// printf("Error allocating the struct\n");
// }
ptr->t = (char*)malloc(strlen(title) + 1);
if (ptr->t == NULL) {
printf("Error allocating the title in the struct\n");
}
ptr->g = (char*)malloc(strlen(genre) + 1);
if (ptr->g == NULL) {
printf("Error allocating the genre in the struct\n");
}
strcpy(ptr->t, title);
strcpy(ptr->g, genre);
}
Finally in printMovieInfo, your current code is printing the first element's data multiple times. You can fix that by indexing into the array to get the element you want:
void printMovieInfo(MovieInfo list[]) {
printf("%-35s %-35s\n", "Title", "Genre");
for (int i = 0; i < kTenItemsEntered; i++) {
// previously: printf("%-35s %-35s\n",list->t,list->g);
printf("%-35s %-35s\n",list[i].t,list[i].g);
}
}

Each time you call getMovieInfo, you're storing the data in a local pointer to allocated memory. That pointer gets lost when the function returns, so newMovieInfo is never populated with anything.
The pointer being passed to the function points to an already existing instance of MovieInfo, so there's no need to allocate memory for it (though you still need to allocate memory for the strings).
Even after this fix, you're only ever updating the first element of the newMovieInfo. You need to pass a pointer to the array element in question when you call getMovieInfo:
getMovieInfo(newMovieInfo + i - 1, title, genre);
Note the -1 here because you're looping from 1 to kTenItemsEntered and array indices in C start at 0. If you changed the loop to go from 0 to kTenItemsEntered-1, you can remove the -1 from the line above.
Your printing function is also only printing the first element of the array, so change the line in the loop body to:
printf("%-35s %-35s\n",list[i].t,list[i].g);

Related

Storing several string with struct in C

with following code I can store one string only.
Main problem is how to store several. If i want to enter another string after the first one it wont do it.
I didnt write it in code but when I type("KRAJ") it should get out of while loop.
typedef struct{
char Objekat[20+1];
char Mjesto[20+1];
char velicina [20];
int cijena;
char kn[3];
char stanje[20];
}Apartmani;
int main()
{
Apartmani *apartmani=(Apartmani*)malloc(sizeof(Apartmani)*50);
while(scanf("%[^,\n],%[^,],%[^,],%d%[^,],%[^\n]", &apartmani[i].Objekat,&apartmani[i].Mjesto,&apartmani[i].velicina,
&apartmani[i].cijena,&apartmani[i].kn, &apartmani[i].stanje )==6)
{
i++;
}
for(p=0;p<i;p++)
{
printf("%s %s %s %d %s %s",apartmani[p].Objekat,apartmani[p].Mjesto,apartmani[p].velicina,apartmani[p].cijena,
apartmani[p].kn, apartmani[p].stanje);
}
}
For example:
string 1: Apartman, Novalja, 100.00 m2, 750000kn, dobro ocuvano.
string 2: Kuca, Ivanbregovia, 20m2, Imtoski, 21252RH, vrijednost-neprocjenjiva.
You should use fgets() plus sscanf().
You should not cast malloc[Do I cast the result of malloc?][1]. Remember to check the return value of malloc, since it can be failed.
change the line of allocating apartmani to:
Apartmani *apartmani= malloc(sizeof(Apartmani)*50);
if(!apartmani) {return -1;}
Do not use & for the input of string.
Check the value of i because its value is limited to 50.
Your code is missing the declaration of i (should be: int i = 0), and the declaration of p also.
Your while loop can be as below:
int i = 0;
char line[100];
while(i < 50 && fgets(line,sizeof(line),stdin))
{
line[strcspn (line, "\n" )] = '\0'; // trip the enter character at the end of line.
int err = sscanf(line,"%20[^,],%20[^,],%19[^,],%d,%2[^,],%19[^\n]", apartmani[i].Objekat,apartmani[i].Mjesto,apartmani[i].velicina,&apartmani[i].cijena,
apartmani[i].kn, apartmani[i].stanje);
if(err != 6)
break;
i++;
}
If I understand you correctly, you want to store several 'Apartmani' structures.
In this case, you have 2 main possibilites :
Using array of structures (Fastest to write but less efficient)
Use linked-list (More efficient but more complex to use)
Examples
1: Using array of structures
#define MAX_APARTMANI 50
int main(void) {
int i = 0;
/* Create Apartmani array */
Apartmani *apartmani_tab[MAX_APARTMANI];
do {
/* loop by using malloc on a single element */
apartmani_tab[i] = (Apartmani *) malloc(sizeof(Apartmani));
/* While check using scanf */
} while (scanf("%[^,\n],%[^,],%[^,],%d%[^,],%[^\n]", apartmani_tab[i]->Objekat, apartmani_tab[i]->Mjesto, apartmani_tab[i]->velicina,
apartmani_tab[i]->cijena, apartmani_tab[i]->kn, apartmani_tab[i]->stanje) == 6 && ++i < MAX_APARTMANI)
/* good pratice: don't forget to free memory ! */
while (--i > 0) {
free(apartmani_tab[i]);
}
return (0);
}
2: Using linked-list
typedef struct Apartmani {
char Objekat[20+1];
char Mjesto[20+1];
char velicina [20];
int cijena;
char kn[3];
char stanje[20];
struct Apartmani *next;/* add pointer to next item in the list */
} Apartmani_t;
Apartmani_t *new_item(void) {
Apartmani_t *new_element = NULL;
new_element = (Apartmani_t *) malloc(sizeof(Apartmani));
if (!new_element)
return (NULL);
memset(new_element, 0, sizeof(*new_element));
new_element->next = NULL;
return (new_element);
}
int main(void) {
/* Initialize Apartmani list*/
Apartmani *apartmani_list = NULL, *current = NULL;
do {
if (!apartmani_list) { /* if empty list */
apartmani_list = new_item(); /* add first item */
if (!apartmani_list) /* prevent malloc errors */
break;
current = apartmani_list; /* link current pointer to list */
} else {
current->next = new_item();
if (!current->next) /* if malloc fails */
break;
current = current->next; /* update current pointer */
}
} while (scanf("%[^,\n],%[^,],%[^,],%d%[^,],%[^\n]", current->Objekat, current->Mjesto, current->velicina, current->cijena, current->kn, current->stanje) == 6) /* While check using scanf */
/* good pratice: don't forget to free memory ! */
while (apartmani_list) {
current = apartmani_list->next;
free(apartmani_list);
apartmani_list = current;
}
}
NB: I have not tried this code but the final version is probably very close to that.

Trying to figure out why my struct pointer is storing data inaccurately

I am trying to improve my C skills so I apologize if my question is long. I am having a hard time understanding as to why my struct pointer holds the wrong value in my program, I tried to debug it but I am still relatively new to C and was hoping one of you could tell me what I'm doing wrong here and how I could improve my code and what to focus on.
I am making a program that stores user data on this struct and then prints it out.
typedef struct table {
char *firstName;
char *lastName;
int id;
}USER;
This function below stores the first name
void firstName(int *counter, int *check, USER *pt) {
for (int i = *counter; i < *check; i++) {
pt[i].firstName = calloc (MAX_LENGTH, sizeof(pt));
printf("Enter First Name: ");
getchar();
fgets(pt[i].firstName, MAX_LENGTH, stdin);
}
}
This is just my bool function returning true or false
bool isTrue(char *decision) {
if(*decision == 'Y') {
return true;
}
else {
return false;
}
}
And this is my main
int main(int argc, char **argv) {
USER *pt = calloc(1, sizeof(pt));
int counter = 0, check = 0;
char decision = '\0';
while (1) {
printf("Would you like to enter a user?(Y/N):");
fgets(&decision, 2, stdin);
strtok(&decision, "\n"); //remove the newline char
if (!isTrue(&decision)) {
break;
}
if (counter != 0) {
pt = realloc(pt, sizeof(pt) * 10); //the 10 is temporary
}
check = counter + 1; // make sure loop only runs once.
firstName(&counter, &check, pt);
++counter; // increment counter;
}
printStruct(pt, &counter);
return 0;
}
When I run it out sometimes it works fine and returns everything and sometimes it skips a value. This is what I get. It skips the value at pointer index 1 and prints garbage instead.
Would you like to enter a user?(Y/N):N
First name at array 0 is Ermir
First name at array 1 is P#1First name at array 2 is Kevin
First name at array 3 is Blaus
First name at array 4 is Adam
Also I was wondering why is it when I realloc here If i do I get a realloc error when I enter the second name.
if (counter != 0) {
pt = realloc(pt, sizeof(pt) * 10); //realloc(pt, sizeof(pt) * counter + 1) wont work
}
char decision = '\0';
...
fgets(&decision, 2, stdin);
You are only allocating 1 char but are at least reading 2 chars into it. Fix by allocating a sufficiently sized array for decision.
Unrelated but in firstName() pt[i].firstName = calloc (MAX_LENGTH, sizeof(pt)); should be pt[i].firstName = calloc (MAX_LENGTH, 1);

C program pointers crashing system calls

// Struct for Country Data
typedef struct
{
char name[50]; // Country name
char code[3]; // Country code
int population; // Country Population
double lifeExp; // Country Life expectancy
} CountryData;
// Struct for Dir File
typedef struct
{
char code[3];
int offSet;
} DirData;
// Function Declarations
void fillCountryStructs(CountryData ** dataPtr, int nLines, int fd);
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines,int fd2);
void sortStructs(DirData **director, int nLines);
int verifyString(char *s1, char *s2);
// Main Function
// - This function starts the program, get the number of lines as a
// parameter, fills the structs and writes the data to the Country
// File and the Directory file.
int main(int argc, char *argv[]) // Always remember to pass an argument while executing
{
// Some variables
int nLines; // The number of lines
char *pEnd; // For String functions
FILE *Fin,*Fout; // File pointers
int fd;
int fd2;
nLines = strtod(argv[1], &pEnd);
CountryData **countryDataPtr; // Array of structs
CountryData **tempStruct;
DirData **director;
// Allocate memory for the struct pointers
countryDataPtr = calloc(nLines, sizeof(CountryData*));
director = calloc(nLines, sizeof(DirData*));
// File Stream for "AllCountries.dat"
if((fd = open("AllCountries.dat", O_RDWR)) ==-1)
err_sys("File not found...\n");
// File Stream for "RandomStruct.bin"
if ((fd2 = open("RandomStruct.bin", O_RDWR)) == -1)
err_sys("Failed to open binary\n");
// Filling the Country stucts
fillCountryStructs(countryDataPtr, nLines, fd);
close (fd);
//fclose(Fin); // Closing the file "AllCountries.dat"
// Writing Binary File
write(fd2, (countryDataPtr[0]->name[0]), sizeof(CountryData));
close (fd2);
//fclose(Fout);
printf("RandomStruct.bin written Sucessfully\n");
// Filling the Directory File
// File Stream for "RandomStructDir.dir"
if ((fd2 = open("RandomStructDir.dir",O_RDWR|O_TRUNC)) != -1)
err_sys("Failed to open binary\n");
fillDirectoryStructs(countryDataPtr, director, nLines, fd2);
sortStructs(director, nLines); // Sorting the structs
// Write the number of lines in the FIRST LINE
// of the Directory File
write(fd2, nLines, sizeof(nLines));
// Writing Directory File after the number of lines was written
write(fd2,(director[0]->code[0]), sizeof(DirData));
close (fd2);
//fclose(Fout);
printf("RandomStructDir.dir written Sucessfully\n\n");
exit(0);
}
// Filling the Country structs
// - This function extracts the data from the file using strtok
// and fills all the structs with their corresponding values.
void fillCountryStructs(CountryData **dataPtr, int nLines, int fd)
{
int curLine = 0; // Current line
int index = 0; // The index
char buf[BUFSIZE]; // The Buffer with the size of BUFSIZE
char *tok; // Token
char *pEnd; // For the String functions
char ch = 'a'; // The temp character
int temPop;
double temLifeExp;
int num=0;
for(curLine = 0; curLine < nLines; curLine++)
{
// Reading each line
dataPtr[curLine] = (CountryData *)calloc(1, sizeof(CountryData));
index = 0;
do
{
read(fd, &ch, 1);
buf[index++] = ch;
}
while(ch != '\n');
// Strtoking...
tok = strtok(buf, ",\n");
index = 1;
while(tok != NULL)
{
tok = strtok(NULL, ",\n");
// Get the Country Code
if(index == 1)
{
strcpy(dataPtr[curLine]->code, tok); // Copying code to the struct
}
// Get the Country Name
if(index == 2)
{
strcpy(dataPtr[curLine]->name, tok); // Copying name to the struct
}
// Get the Country Population
if(index == 7)
{
temPop = (int)strtol(tok, &pEnd, 10);
dataPtr[curLine]->population = temPop; // Copying population to the struct
}
// Get the Country Life expectancy
if(index == 8)
{
num=countchar(tok);
printf ("The number of characters entered is %d\n", num);
printf ("The character entered is %s\n",tok);
temLifeExp = strtod(tok, &pEnd);
dataPtr[curLine]->lifeExp = temLifeExp; // Copying life expectancy to the struct
}
index++;
}
}
}
int countchar (char list[])
{
int i, count = 0;
for (i = 0; list[i] != '\0'; i++)
count++;
return (count);
}
// Filling the Directory Structs
// - This function fills the directory with the offset
void fillDirectoryStructs(CountryData **dataPtr, DirData **director, int nLines, int fd2)
{
int i = 0;
for(i = 0; i < nLines; i++)
{
strcpy(director[i]->code, dataPtr[i]->code); //It crashes in this Line
director[i]->offSet = sizeof(CountryData) * (i);
}
}
// Sorting the Dir Structs
// - This function sorts the Directory Structs.
void sortStructs(DirData **director, int nLines)
{
int maxNumber;
int i;
DirData **temp;
temp = calloc(1, sizeof(DirData));
// Sorting the array of pointers!
for(maxNumber = nLines - 1; maxNumber > 0; maxNumber--)
{
for(i = 0; i < maxNumber; i++)
{
if((verifyString(director[i]->code, director[i+1]->code)) == 1)
{
temp[0] = director[i];
director[i] = director[i+1];
director[i+1] = temp[0];
}
}
}
}
// Veryfying the strings
// - This function compares two strings and return a specific value
// accordingly.
int verifyString(char *s1, char *s2)
{
int i;
if(strcmp(s1,s2) == 0)
return(0); // They are equal
for(i = 0; s1[i] != 0; i++)
{
if(s1[i] > s2[i])
return(1); // s1 is greater
else if(s1[i] < s2[i])
return(2); // s2 is greater
}
return (2); // s2 is greater
}
So I get segmentation fault and I have no Idea why? maybe is something about the pointers. I specified where it crashes (void fillDirectoryStructs) that method the first line.
When I compile I get :
Countries.c: In function 'main':
Countries.c:68: warning: passing argument 2 of 'write' makes pointer from integer without a cast
Countries.c:84: warning: passing argument 2 of 'write' makes pointer from integer without a cast
Countries.c:86: warning: passing argument 2 of 'write' makes pointer from integer without a cast
Countries.c:232:2: warning: no newline at end of file
I don't know a lot about pointers but I have to use system calls, so I can't use any of the FILE * functions (fwrite(), etc) that is why I'm using plain write() and read().
When I run it I get segmentation fault when It gets to that point I just specified.
for test purposes I'm trying to print this
printf("test: %s\n", countryDataPtr[0]->code[0]);
instead of writing and it crashes there, why? what am I doing wrong? shouldn't that get the code of that first country in my struct? thanks
Well, you need to listen to your compiler and take its warnings seriously.
This:
write(fd2, nLines, sizeof(nLines));
is wrong, and would explain the warning. The variable nLines has type int, but if you look at the [documentation for write()] you can see that the 2nd argument has type void *.
So it will interpret your integer value as a pointer, and start reading memory which you have no right to be reading.
You need:
write(fd2, &nLines, sizeof nLines);
Note that sizeof is not a function, it only needs parenthesis when the argument is a type name (since it then needs a cast expression to the type in question, and casts are writen as a type name enclosed in parenthesis).
Also, you need to be prepared for the reality that I/O can fail. The write() function has a return value which you should be checking.
There are a number of other problems with your code, in addition to the serious one unwind pointed out.
This:
CountryData **countryDataPtr; // Array of structs
is not an Array of structs. Once allocated, it could be an array of pointers to structs.
This:
write(fd2, (countryDataPtr[0]->name[0]), sizeof(CountryData));
does not write one CountryData instance (much less a whole array of them). It takes the integer value of the first character of the first element's name, and treats it as a pointer just like you do with nLines.
If you want to write the first element, it would look like this:
write(fd2, countryDataPtr[0], sizeof(CountryData));
and if you wanted to write all the elements, you'd either need a loop, or a contiguous array of structs you can write in one go.

Implementing a stack of "strings" in C

I'm trying to implement a stack structure in C, for storing char arrays into.
I have the following code:
typedef struct {
size_t size;
char **data;
} loods1;
loods1 *init(void) {
loods1 *loods = malloc(sizeof(loods1));
loods->data = malloc(sizeof(char *) * STACK_MAX);
for (int i = 0; i < STACK_MAX; i++) {
*(loods->data + i) = malloc(LABEL_LENGTH_MAX * sizeof(char));
}
loods->size = 0;
if (loods == NULL) {
perror("malloc failed\n");
return NULL;
}
return loods;
}
int empty(loods1 *loods) {
return (loods->size == 0);
}
void push(loods1 *loods, char *name) {
if (loods->size == STACK_MAX) {
perror("Stack is full\n");
exit(0);
}
else {
*((loods->data) + loods->size++) = name;
}
}
char *pop(loods1 *loods) {
if (loods->size == 0) {
printf("size == 0\n");
return NULL;
}
else {
printf("%s \n", *(loods->data + 1));
return *(loods->data + (--loods->size));
}
}
int delete(loods1 *loods) {
for (int i = 0; i < STACK_MAX; i++) {
free(*(loods->data + i));
}
free(loods->data);
free(loods);
}
There are 2 problems: first off, every time I add a new element to the stack, it overwrites all existing elements (if '3' and '11' are added and I want to add '15', the new stack will look like '15', '15', '15'). And when I want to pop the stack, the popped value is empty. Not null, but an empty string or something?
I have no idea what I'm doing wrong, but there seems to be a mistake somewhere, obviously.
Sammy
In push function, if you are passing char*, it will divert your pointer to where the char * is, and when you do p++, it will go from the char* you passed.
Try change push definition to:
void push(loods1 *loods, const char *name) {
if (loods->size == STACK_MAX) {
perror("Stack is full\n");
exit(0);
}
else {
strcpy((loods->data)[loods->size++], name);
}
}
From here you might as well need some other changes to your calling program.
Also when you free it, free the single loods does not free all memory you allocated.
I flicked through the code and it seems to be ok, I think the problem is in your client.
Your only store pointers in the stack, you're probably pushing the same pointer on the stack but rewrite the string it points to.
Note that if you really only want to store pointers your 3rd malloc is wasting space and also creates a memory leak.

C programming pointers and char array problems

I want to pass the contents of an array to another method and have that method print out the entire array - how would i do this?
Currently:
I'm returning an array from a function.
char* search_value(struct PDB *llist)
{
int realID = -7;
int x = 0;
int task = 0;
char *received;
char theMessage[100];
theMessage[0] = '\0';
printf("Your choice: `Search'\n");
printf("Enter the value you want to find: ");
scanf("%d", &task);
while(llist->data1 != NULL)
{
if(task == llist->taskID)
{
realID = llist->taskID;
strcpy(theMessage, llist->data1);
break;
}
}
return theMessage;
}
i'm getting the return value:
void getMessage(const int GET_MESSAGE)
{
char * received = NULL;
int x = 0;
received = search_value(llist);
printf("%s", received);
}
I want to somehow print the entire value (rather than just the first value to which the pointer is pointing at - how would i do this?
A few corrections and it should work:
// - struct contents shouldn't be changed by the function, make its pointer const.
// - pass a pointer to an allocated array as parameter
char* search_value(const struct PDB *llist, char* theMessage)
{
int realID = -7;
int x = 0;
int task = 0;
char *received;
theMessage[0] = '\0';
printf("Your choice: `Search'\n");
printf("Enter the value you want to find: ");
scanf("%d", &task);
while(llist->data1 != NULL)
{
if(task == llist->taskID)
{
realID = llist->taskID;
strcpy(theMessage, llist->data1);
break;
}
}
return theMessage;
}
void getMessage(const int GET_MESSAGE)
{
char received[100]; // allocate the array outside the function
int x = 0;
search_value(llist, received); // pass a pointer to the first element
printf("%s", received);
}
You have an issue with variable scope here: theMessage is local to the function search_value, so you're returning a pointer to an array which no longer exists once the function completes.
Instead you should use malloc() to allocate the space for theMessage and then subsequently free() it later on outside of the function when you're finished with it —  however this can often lead to memory leaks if you're not diligent about cleaning up after yourself.
You can allocate the memory like so:
char * message = malloc(100);
One alternative would be to allocate the buffer in getMessage() and pass a pointer to the buffer into search_value which could then write into it:
void getMessage(const int GET_MESSAGE)
{
char received[100];
int x = 0;
search_value(llist, received);
printf("%s", received);
}
void search_value(struct PDB *llist, char * buffer)
{
// write to buffer
}
Another option is to declare a char * pointer inside getMessage(), pass a pointer to a pointer into search_value() and again use malloc() to allocate space for the buffer.
Finally, this is a minor style criticism, but you'd do well to learn to stick to one convention for naming your functions, search_value and getMessage are not consistent names, and this will irk many a coder that you work with.
You have several problems with your code. I'm guessing that you want to search a list for some value, then return that value.
The first problem is that you do not actually iterate over the list, but only check the same item over and over again. The other problem is that you return a pointer to a local variable. This is undefined behavior, because as soon as the function returns the memory the pointer points to can be used for something else.
I suggest you change your code as follows:
char *search_value(struct PDB *llist, char *theMessage, size_t theMessageMaxLength)
{
int realID = -7;
int task = 0;
printf("Your choice: `Search'\n");
printf("Enter the value you want to find: ");
scanf("%d", &task);
while(llist != NULL && llist->data1 != NULL)
{
if(task == llist->taskID)
{
realID = llist->taskID;
strncpy(theMessage, llist->data1, theMessageMaxLength);
theMessage[theMessageMaxLength] = '\0';
break;
}
llist = llist->next; /* Assuming the field is named "next" */
}
return theMessage;
}
void getMessage(const int GET_MESSAGE)
{
char *received = NULL;
char theMessage[100];
/* Subtract 1 from the size, for the terminating '\0' */
received = search_value(llist, theMessage, sizeof(theMessage) - 1);
printf("%s", received);
}
the array you are returning is local to that function. Either the calle function shall provide the array in which it expects the values or use static array.

Resources