Reputation: 21
So I have an C string (array of chars) in my main method, when I pass it as parameter into another method, its size changes.
void method(char* arr){
printf( "%u\n", sizeof(arr) ); //returns 4, in my program.
arr = "hello "; //executes just fine
char arr2[9] = "people";
strcat(arr, arr2); // (1) here is where it crashes down
int i = 0; while(i < sizeof(arr2)){ arr[i+6] = arr2[i]; i++;} // (2) this causes it to crashdown too
}
int main(){
char array[33];
printf("%u\n", sizeof(array) ); //returns 33, in my program.
method(array);
}
Why does this happen?, how can I fix it? Does this mean I cannot add more values to the C string? I suspect this may be the cause of the constant crashdown of my program (whenever I try to add n). Neither does the line marked by (1) nor (2) works. Is there a workaround?
Upvotes: 2
Views: 2546
Reputation: 31435
"Correct" code in C.
int method(char* arr, size_t size, bool useStrcat)
{
const char * prefix = "hello "; // could be static
size_t prefixLen = strlen( prefix ); // which will be 6. Could be static.
strncpy( arr, "hello ", size );
char arr2[] = "people";
if( useStrcat )
{
strncat(arr, arr2, size - prefixLen);
}
else
{
for( int i = 0; i < sizeof(arr2) && i < (size - prefixLen); ++i )
{
arr[i+prefixLen] = arr2[i];
}
}
return prefixLen + sizeof(arr2);
}
Note that arr2 includes its null terminator as part of its size so it will be written when your buffer does not reach capacity.
Many programs that do this will return for you the number of character they wanted to write and will often be called twice, the second time with a large enough buffer, and sometimes the first call is made purposely with a 0-size buffer just to obtain the count.
Test this method called from main by passing it: - differing values for useStrcat - a buffer size smaller than what you need for the output (in this case 13).
Beware of printing a not-terminated string though. Your "main" can always allocate 13 anyway and put in the null itself, e.g.
int main()
{
char buf[13] = {0};
method( buf, 12, false ); // do not use strcat
puts( buf );
}
Upvotes: 0
Reputation: 1673
Since you are writing C++ (even though it is a lot like C), change "method" (poor choice for a name, if I may say so) to --
void method(char (&arr)[33]) // I would recommend std::string instead
{
cout << sizeof(arr) << endl; // should return 33 in your program.
strcpy(arr, "hello "); // should execute per behaviour defined by ISO
char arr2[] = "people"; // Note that arr2 is followed by '[' and an immediate ']'
strcat(arr, arr2); // Now this should work, although std::string is still better.
}
Note that even this is like C (because it uses vanilla character arrays rather than std::string).
Upvotes: 0
Reputation: 500167
Here is what happens:
In main()
, you're applying sizeof()
to the array, so you get the size of the array.
When main()
calls method()
, the array decays into a pointer (since method()
takes a pointer).
In method()
, you are applying sizeof()
to the pointer, so you get the size of the pointer.
To fix, pass the actual allocated size of arr
into method()
as an additional argument, and use that argument as a limit on how much stuff you're permitted to write into arr
.
As a side note, the following doesn't do what you expect:
arr = "hello "; //executes just fine
This doesn't modify the underlying array; it simply re-points arr
to the string literal. You should be using strncpy()
instead of the assignment.
Upvotes: 8
Reputation: 93410
Naturally,
cout << sizeof(arr) << endl; //returns 4, in my program.
prints 4, because here you are actually printing sizeof(char*)
, i.e. the size of the pointer, while in the main()
function you are doing the equivalent of sizeof(sizeof(char) * 33)
.
How to fix that: well, the problem is your function signature:
void method(char* arr)
Working with functions that receives pointers to arrays requires you to add a parameter in the function signature to specify the size of the array:
void method(char* arr, int arr_size)
It's the only way.
Upvotes: 2
Reputation: 3600
If you would like to know size in the function there are 3 ways:
void method(const std::string& arr);
and you will be able to use arr.size();
to get the size of the string. If you write in C++ the safer way is to use std::string
instead of char*
.Upvotes: 0
Reputation: 385098
You're doing sizeof
on a pointer, not on a array. You cannot pass an array by value into a function. You just can't.
You're then replacing the local copy of said pointer with a new one that points to "hello"
. Then expecting to be able to get the 8th character of the string "hello"
is obviously not going to work.
std::string
and std::vector
.Upvotes: 2