This is supposed to read a surname from a string and display it instead of the whole string. More specificaly, it reads a string, identifies the adress of the last space and copies to another string what's between it and '\0'.


Code:
#include <stdio.h>
int strlen (char*s)
{
   int i;
   for(i=0; s[i]!='\0'; i++)
   ;
   return i;
}

char *strrchar(char *s, char ch)
{
   int i;
   for(i=strlen(s); i>=0 && s[i]!=ch; i--)
   ;
   if (i>-1)
   return s+i;
   else
   return NULL;
}

char *name(char *s)
{
   int x;
   char *string, *ptr;
   for( x = 0, ptr = strrchar(s, ' ')+1; *ptr!= '\0'; x++, ptr++)
   string[x] = *ptr;
   string[x] = '\0';
   
   return string;
}

main()
{
char *s = "JANE DOE";
   if(strrchar(s, ' ')== NULL)
   {
      printf("Invalid String\n\n");
      return;
   }
   else
   printf("%s\n\n", name(s));
}


The problem is here:

Code:
main()
{
char *s = "JANE DOE";
   if(strrchar(s, ' ')== NULL)
   {
      printf("Invalid String\n\n");
      return;
   }
   else
   printf("%s\n\n", name(s));
}


If I write it like this, the cmd crashes. The compiler doesn't show any error or warning (besides from "conflicting types strlen blah blah")

But if I write it like this, it works fine:

Code:
main()
{
   printf("%s\n\n", name("JANE DOE"));
}


It also works just fine like this:


Code:
main()
{

   if(strrchar("JANE DOE", ' ')== NULL)
   {
      printf("Invalid String\n\n");
      return;
   }
   else
   printf("%s\n\n", name("JANE DOE"));
}


So the problem must be in the declaration of the string s.
What could be causing this?
From valgrind
Code:
==6799== Use of uninitialised value of size 8
==6799==    at 0x40066D: name (test.c:26)
==6799==    by 0x4006D6: main (test.c:41)
string is not initialized. malloc can be used for that.
AHelper wrote:
From valgrind
Code:
==6799== Use of uninitialised value of size 8
==6799==    at 0x40066D: name (test.c:26)
==6799==    by 0x4006D6: main (test.c:41)
string is not initialized. malloc can be used for that.


What's malloc?
So, what's exactly the problem?

Code:
#include <stdio.h>
int strlen (char*s);
char *strrchar(char *s, char ch);
char *nome(char *s);
int strlen (char*s)
{
   int i;
   for(i=0; s[i]!='\0'; i++)
   ;
   return i;
}

char *strrchar(char *s, char ch)
{
   int i;
   for(i=strlen(s); i>=0 && s[i]!=ch; i--)
   ;
   if (i>-1)
   return s+i;
   else
   return NULL;
}

char *nome(char *s)
{
   int x;
   char *ptr;
      if (strrchar(s,' '))
         return ptr=(strrchar(s,' ')+1);
      return s;
}
main()
{
   char *s= "Jane Doe";
   puts(nome(s));
}

I fixed it, but apparently I can't do this:


Code:
main()
{
   char *s;
        gets(s);
   puts(nome(s));
}


But, this works:


Code:
main()
{
   char s[100];
   gets(s);
   puts(nome(s));
}


I don't know much, but I assume this has to do with that memory allocations thing?
malloc is the standard C function name for a function for allocating memory.
I believe it is because the OS has no idea how much memory to set aside for your variable. This is why your compiler throws this error, because it has no idea how large the character array s is, and needs to be initialized. You can do this manually, and avoid this by using malloc: Click Here

Of course, there is C++ which has new/delete as well. Do you have any particular reason for using the C standard?
In your second code, you are reserving 100 bytes and you declare a pointer named s that points to those 100 bytes. Then you call "get" on this s. "get" can write within the 100 bytes you reserved.

In your first code, you are not reserving any byte and you declare a pointer named s that probably points somewhere it shouldn't. Then you call get on this s. "get" tries to write where s points which is not a good idea.

So yeah, as others said, either use the second code or use a malloc (and a free).
Hayleia wrote:
In your second code, you are reserving 100 bytes and you declare a pointer named s that points to those 100 bytes. Then you call "get" on this s. "get" can write within the 100 bytes you reserved.

In your first code, you are not reserving any byte and you declare a pointer named s that probably points somewhere it shouldn't. Then you call get on this s. "get" tries to write where s points which is not a good idea.

So yeah, as others said, either use the second code or use a malloc (and a free).


What do you mean "that probably points somewhere it shouldn't"?


MateoConLechuga wrote:
I believe it is because the OS has no idea how much memory to set aside for your variable. This is why your compiler throws this error, because it has no idea how large the character array s is, and needs to be initialized. You can do this manually, and avoid this by using malloc: Click Here

Of course, there is C++ which has new/delete as well. Do you have any particular reason for using the C standard?


I like your answer, thank you.

I use C standard because I'm just a beginner and C seemed like a good language to start.
Quote:
What do you mean "that probably points somewhere it shouldn't"?


Pointers are called pointers because they point to locations in memory. Your computer likely has several GB of memory, and only a very few KB are likely allocated to your program as it currently exists, and exactly which of those are currently held by your program is subject to change as the program runs. Each function call will allocate some memory for local usage and then free it when you return from the function. Each call to malloc will also allocate some memory, and freeing it will make it unusable to your program.

Thus, there are all sorts of way you can point to locations that are no longer valid, or that were never valid to begin with. You might also be pointing to a valid location where you haven't put any valid data, and thus be reading gibberish out of it.
Quote:
What do you mean "that probably points somewhere it shouldn't"?


Well, a pointer just points to a memory address. If you don't tell your computer where it should be pointing, it could be anywhere in your computer's memory, which could be somewhere vital that you don't want to touch.
So, those errors might mess up my computer?
AliceIsDead wrote:
So, those errors might mess up my computer?


No, because your OS will prevent you from accessing these portions unless you do something purposeful to get around this. This is referred to as a Segmentation Fault, I believe.
MateoConLechuga wrote:
AliceIsDead wrote:
So, those errors might mess up my computer?


No, because your OS will prevent you from accessing these portions unless you do something purposeful to get around this. This is referred to as a Segmentation Fault, I believe.


Oh, that's a relief Very Happy
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement