Hi!
I've encountered another problem,
The code below is just the part of the code where the error occurs

int FindStr(FILE *f, char *str)
{
 int s_pos; //string position in the text
 int c_pos; //char position in the text
 char *string;
 char ccnt; //char count

 s_pos = -1;
 c_pos = 0;
 string = malloc(strlen(str));

At the last line the compiler(DEV C++)says that there is an invalid conversion from void* to char*....
I didn't understand the error.
Can anyone explain?
Thanks in advance

Anurag

Edited 4 Years Ago by Nick Evan: closed

Hi anuragcoder :-)

The error is caused by the fact that malloc returns a void*.
You can not make an implicit cast of a void* to another type, you have to make it explicit:

string = (char*)malloc(strlen(str));

BTW...

A string is terminated with the '\0' escape-character.
When you enter the string "Hello World" the string is actually stored as "Hello World\0".

However strlen only returns the number of actual characters in the string.
The number of char in the string "Hello World" is 12 (remember the '\0') but strlen does not count the '\0' and returns 11.

The reason mention this is: When you allocate memory for your string, you have to remember to allocate the extra memory for the '\0'.

Like this:

string = (char*)malloc(strlen(str)+1);

Edited 6 Years Ago by mbulow: n/a

string = (char*)malloc(strlen(str)+1);

But my dear friend, Index starts from 0, so 0-11 is infact 12. So the OP's method is correct minus the typecast part.

Hi nbaztec :-)

Please compile this piece of code, and tell me if the output strings are identical:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   char *pText = "Hello World";
   char *pCopy;

   //This malloc does NOT allocate memory for the terminator
   pCopy = (char*)malloc(strlen(pText));

   //Now lets copy the string
   for(int i = 0; i < strlen(pText); i++)
      pCopy[i] = pText[i];

   //Now print the two strings
   printf("pText: %s\n", pText);
   printf("pCopy: %s\n", pCopy);
}

They are not, are they...
You have not copied the terminator from the original string to the copy.
Now add +1 to both strlen-calls, and try again.

The number of char's in the string "Hello World" is 12. The 11 char's from the text, plus 1 char for the terminator ('\0').

strlen returns the number of char's in the string EXCLUDING the terminator. Result: 11.

In this line:

string = (char*)malloc(strlen(str));

anuragcoder allocates memory for the 11 char's, but forgets the space needed for the terminator.

Edited 6 Years Ago by mbulow: n/a

Comments
Yep thats right
Quite so.

Hi nbaztec :-)

Please compile this piece of code, and tell me if the output strings are identical:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   char *pText = "Hello World";
   char *pCopy;

   //This malloc does NOT allocate memory for the terminator
   pCopy = (char*)malloc(strlen(pText));

   //Now lets copy the string
   for(int i = 0; i < strlen(pText); i++)
      pCopy[i] = pText[i];

   //Now print the two strings
   printf("pText: %s\n", pText);
   printf("pCopy: %s\n", pCopy);
}

They are not, are they...
You have not copied the terminator from the original string to the copy.
Now add +1 to both strlen-calls, and try again.

The number of char's in the string "Hello World" is 12. The 11 char's from the text, plus 1 char for the terminator ('\0').

strlen returns the number of char's in the string EXCLUDING the terminator. Result: 11.

In this line:

string = (char*)malloc(strlen(str));

anuragcoder allocates memory for the 11 char's, but forgets the space needed for the terminator.

I quoted a part of your post for a reason. In that you are just wasting memory.
Of course strlen() returns the Number of characters MINUS the Null but in a string indexing starts from 0.
So
str[11] is sufficient to hold 11 characters plus 1 null char. As 0-11 is 12 characters in all

Programming is like WYCIWYG(What You Code Is What You Get), in your first attempt you didn't copy the NULL char from source to destination hence the string showed abnormal behavior. As far as allocation is concerned the OP allocated the correct amount of bytes to accommodate his string .

Edited 6 Years Ago by nbaztec: A minus sign lead to a fall in my reputation.

Comments
This is just wrong

Of course strlen() returns the number of chars - NULL but in a string indexing starts from 0.
So
str[11] is sufficient to hold 11 characters plus 1 null char. As 0-11 is 12 characters in all

No very VERY wrong. strlen does not return the size of the array holding the string it returns the number of characters in the string up to but not including the NULL.

Try this code for proof

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   char Text[] = "Hello World"; // Allocate an array just the right size of the text

   //Now print the two strings
   printf("Text: %s\n", Text);
   printf("strlen: %d\n", strlen(Text));
   printf("size: %d\n", sizeof Text);
}

And you will see that strlen returns a value 1 less than the size of the array required to hold the string.

Output

Text: Hello World
strlen: 11
size: 12

Edited 6 Years Ago by Banfa: n/a

@Banfa

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   char *pText = "Hello World";
   char *pCopy;
   char st[11]="Hello World";

   //malloc only till strlen
   pCopy = (char*)malloc(strlen(pText));

   //Now lets copy the string + copy Null char from string
   for(int i = 0; i <= strlen(pText); i++)
      pCopy[i] = pText[i];

   //Now print strings
   printf("pText: %s\n", pText);
   printf("pCopy: %s\n", pCopy);
   printf("pCopy: %s\n", st);
   getch();
}

The above code will print "Hello World" thrice. My above post. Cannot believe you flagged it as wrong.

No very VERY wrong. strlen does not return the size of the array holding the string it returns the number of characters in the string up to but not including the NULL.

That's what I sed.

Of course strlen() returns the number of chars - NULL but in a string indexing starts from 0.

I sed number of chars - NULL (Minus NULL).

Edit: Allow me to change my earlier comment so no one else gets confused. It is Number of characters MINUS the Null.

Edited 6 Years Ago by nbaztec: n/a

Please take an extra look at what you are doing in your code:

You allocate enough memory for 11 char's, right?! :)

What happens in the for-loop? You copy 12 char's into the allocated 11 char's.

The 12th char's get copied into memory that might belong to some other variable, or even executable code.

That will be a fun bug to find, if you do that in a big program.

You allocate enough memory for 11 char's, right?

It is for 11 char and a NULL.

int a[11] can store 12 elements,a[0] to a[11]. So can str[11]

The Loop goes through 0 to 11(Length), i.e. for 12 elements
'H','e''l','l','o',' ','W','o''r','l','d','\0'

NO!

int a[11] can only store 11 elements;

int a[11] creates an array with 11 elements. Indexed as a[0] to a[10]

Edit: Allow me to change my earlier comment so no one else gets confused. It is Number of characters MINUS the Null.

Sorry, but you are not right about it - please start believing in what people are saying.

size_t strlen(const char *s);

The strlen function computes the length of the string pointed to by s.

Returns
The strlen function returns the number of characters that precede the terminating null character.

Then consider the following ..

// 11 chars is NOT enough to hold the string "Hello World"
char st[11]="Hello World";

This line compiled with g++, results in an error:

main.cpp:3: error: initializer-string for array of chars is too long

Isn't your compiler saying anything?

This thread is going too far of-topic (and is becoming more C than C++). The OP said his problem was solved, so I you two (nbaztec & mbulow) would like to continue this discussion, please feel free to start a new thread in the C-forum.

[closed]

[edit]

And btw: mitrmkar is right.

Edited 6 Years Ago by Nick Evan: n/a

heheh that was funny, yes you need to allocate 12 bytes, 11 won't do, just because the first index is zero you still count that as one byte.

This question has already been answered. Start a new discussion instead.