Reputation: 267
I'm trying to write a program in C. I am pretty fluent in Java but I don't know much C, I'm trying to learn the syntax. This program doesn't really have a goal I'm just learning to compare strings, print out stuff, learn how to work with arrays and so on. The program returns no errors or warning, and it runs fine, but after it finishes command prompt says the program has stopped working. Here is the code:
#include<stdio.h>
#include<string.h>
void printVowlOrElse(char *name[5]){
int i;
for (i = 0; i < sizeof(name) ; i++){
char *tester[2] = {"a", "b"};
if (strcmp(name[i],tester[i]) == 0){
printf("letter is %s at \n", name[i]);
}
}
}
main()
{
printf("Hello World!! \n");
char* myName[2] = {"a", "b"};
printVowlOrElse(myName);
}
The output is:
Hello World!!
letter is a at
letter is b at
Which is correct since both arrays have the same thing, however I dont understand why it crashes. What am I missing?
Upvotes: 0
Views: 6102
Reputation: 19
char *name[]; (to read it start with 'variable name' go to its right and then left, cover right again and then left, so on... untill you finish on it)
Thus it is read as " 'name' is an array of pointers to chars." so if you are doing sizeof(name), it returns the size of the array and hence, array length can be calculated by sizeof(name)/sizeof(name[0]);
#include<stdio.h>
int main()
{
char *name[5];
printf("%d\n", sizeof(*name));
printf("%d\n", sizeof(name));
return 0;
}
output as:
4
20
Explanation:
1) *name, refers to name[0] that is first element of array which is a pointer. 4 bytes in that case.
2) name, is actually an array of those many pointers as its elements. So, it returns size of array = 4*5 = 20 bytes
Now, if you have declaration as char (*name)[];
this will be read as " 'name' is a pointer to array of chars." Thus, sizeof(name) will be 4 bytes. sizeof(*name) will give size of the array. Because *name refers to array of chars.
Hope this helps...
Upvotes: 1
Reputation: 5181
Your program is crashing because printVowlOrElse
accepts a char*
array of length 5, while you are only passing it a char*
of length 2.
You iterate from 0 to sizeof(name)
, which will return sizeof(char**)
, and go out-of-bounds of the length 2 array you provide.
It's actually fairly dangerous because depending on your compiler, I think there's a potential to have a valid memory address floating around past the last element of your static array in main
. Since I debugged this using VC++ (yes, I cheated and used a C++ compiler), the debugging runtime memory marks all uninitialized stack memory with 0xCCCCCCCC
, which is an invalid read location, thus causing a crash. Your memory values may differ.
Note that using sizeof(name)
is also not sufficient. name
is an array of char*
, thus a char**
, and sizeof
is going to return the size in number of bytes, not number of elements. So, you get 4 since a pointer is 4 bytes when compiled for 32 bit architecture. Use sizeof(name) / (sizeof(char*))
instead. Or, even more generically, sizeof(name) / sizeof(name[0])
, once you know that name[0]
is valid.
Upvotes: 1
Reputation: 442
sizeof(name) does not return length of array, it returns size of pointer (for 32 bit 4 bytes). You should provide length of array to the function printVowlOrElse.
You can write printVowlOrElse as:
void printVowlOrElse(char *name[], int size)
{
int i;
for (i = 0; i < size; i++) {
char *tester[2] = { "a", "b" };
char result = compare_string(name[i], tester[i]);
if (result == 0) {
printf("letter is %s at \n", name[i]);
}
}
}
int main()
{
printf("Hello World!! \n");
char* myName[2] = { "a", "b" };
printVowlOrElse(myName, 2);
return 0;
}
Upvotes: 1