Reputation: 21
So I am trying to avoid using strings for this. I am basically trying to make a string array.
char **hourtimes = (char**)malloc(100 * sizeof(char*));
for (int i = 0; i < 100; i++) {
(*hourtimes) = (char*)malloc((100 * sizeof(char)));
}
So I made a string array basically here
Now, I want to make hourtimes[0] = "twelve"
;
I tried doing *hourtimes = "twelve";
but I get the same error, I think this works in c, but I'm using c++
hourtimes[0][0] = 't';
hourtimes[0][1] = 'w';
etc works just fine but that would be too cumbersome
Upvotes: 0
Views: 14033
Reputation: 4370
*hourtimes = "twelve"
is setting *hourtimes
to point to an immutable string literal. You are then trying to modify that immutable string. What you want to do is copy "twelve" into *hourtimes.
strcpy(hourtimes[0],"twelve");
Note: This answer was written at a time when the question was tagged for C. C++ will have different preferred ways of doing this kind of thing.
Upvotes: 5
Reputation: 598319
In your allocation loop, (*hourtimes)
is the same as hourtimes[0]
, so you are assigning your allocated sub-arrays to the same slot in the main array on each loop iteration, causing memory leaks and uninitialized slots. You need to use hourtimes[i]
instead:
char **hourtimes = (char**)malloc(100 * sizeof(char*));
for (int i = 0; i < 100; i++) {
hourtimes[i] = (char*)malloc(100 * sizeof(char));
}
And don't forget to deallocate the arrays when you are done with them:
for (int i = 0; i < 100; i++) {
free(hourtimes[i]);
}
free(hourtimes);
Now, a string literal has type const char[N]
, where N
is the number of characters in the literal, + 1 for the null terminator. So "twelve"
would be a const char[7]
.
Your arrays only allow char*
pointers to be stored, but a const char[N]
decays into a const char*
pointer to the first char
. You can't assign a const char*
to a char*
, thus the compiler error.
Even if it were possible to do (which it is, but only with a type-cast), you shouldn't do it, because doing so would cause a memory leak as you would lose your original pointer to the allocated array, and worse free()
can't deallocate a string literal anyway.
What you really want to do is copy the content of the string literal into the allocated array storage. You can use strncpy()
for that:
strncpy(hourtimes[0], "twelve", 100);
Now, with all of that said, this is the C way of handling arrays of strings. The C++ way is to use std::vector
and std::string
instead:
#include <string>
#include <vector>
std::vector<std::string> hourtimes(100);
...
hourtimes[0] = "twelve";
Upvotes: 1
Reputation:
The error message tells you exactly what's wrong: You can't assign a const char *
to a char *
. What does that mean, though?
Both const char *
and char *
are types. They are, in fact, very nearly the same type; one is a pointer to a character, and the other is a pointer to a constant character. That means that the latter can't be changed1; that's, after all, what "constant" means. So when you try to tell the compiler to treat a pointer to a constant type as a pointer to a non-const
type, it'll give you an error -- because otherwise it'd have no way to guarantee that the string isn't modified.
"whatever"
is always a const char *
, not a char *
, because that's stored in memory that's generally not meant to be modified, and the compiler can make some really neat optimizations if it can safely assume that it's unchanged (which, because it's const
, it can).
I won't tell you how to "properly" write the code you're going for, because if you're using C++, you should be using std::vector
and std::string
instead of anything with pointers whenever possible, and that probably includes here. If, for whatever reason, you need to use pointers, the comments have covered that well enough.
1: Okay, yes, it can -- but that's outside the scope of this answer, and I don't want to confuse any beginners.
Upvotes: 2
Reputation: 26763
This is a string literal, which can be used as a pointer to a constant char
, but not as a pointer to a non-const char.
"twelve"
You do however attempt to assign it to a pointer to non-const char.
hourtimes[0] = "twelve";
That is what the compiler does not like.
Upvotes: 0