27

Possible Duplicate:
C++ deprecated conversion from string constant to 'char*'

I want to pass a string via char* to a function.

 char *Type = new char[10];
 Type = "Access";  // ERROR

However I get this error:

 error: deprecated conversion from string constant to 'char*'

How can I fix that?

Community
  • 1
  • 1
mahmood
  • 23,197
  • 49
  • 147
  • 242
  • 9
    If you overwrite `Type` you generate a memory leak. – 0xbadf00d Nov 14 '11 at 18:48
  • 2
    Any suggestion for a "fix" would probably miss the fact that there's most likely no reason for you to do what you're doing. Post the bigger picture for a more useful answer. – Kerrek SB Nov 14 '11 at 18:49
  • Go over how pointers work again. (If you haven't been over pointers yet, go over them.) You wouldn't assign to an array like `char Type[10]; Type = "Access";` would you? – Chris Lutz Nov 14 '11 at 18:49

4 Answers4

39

If you really want to modify Type:

char *Type = new char[10];
strcpy( Type, "Access" );

If you don't want to modify access:

const char *Type = "Access";

Please note, that, however, arrays of char in C and in C++ come with a lot of problems. For example, you don't really know if the call to new has been successful, or whether it is going to throw an exception. Also, strcpy() could surpass the limit of 10 chars.

So you can consider, if you want to modify type later:

std::string Type = "Access";

And if you don't want to modify it:

const std::string Type = "Access";

... the benefit of using std::string is that it is able to cope with all these issues.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Baltasarq
  • 12,014
  • 3
  • 38
  • 57
  • 5
    Note that `strcpy()` doesn't check that there's enough room in the destination for the value being copied. If the length of the string literal were longer than 9 characters, the `strcpy()` call would create a buffer overflow (which the compiler probably wouldn't tell you about). Oh, and you should verify that the `new` succeeded before trying to copy into the newly allocated buffer. Really, for C++ `std::string` is almost certainly a better solution; it has some overhead, but it takes care of all these allocation issues for you. – Keith Thompson Nov 14 '11 at 22:11
  • Yes, @Keith Thompson, that's a good point. I'll modify my answer to take it into. – Baltasarq Nov 15 '11 at 09:19
12

There are a couple of things going on here.

char *Type = new char[10];

This create a char* pointer named Type and initializes it to point to the first element of a newly allocated 10-element array.

Type = "Access";  // ERROR

This assignment doesn't do what you think it does. It doesn't copy the 6-character string "Access" (7 characters including the terminating '\0') to the array you just created. Instead, it assigns a pointer to the first element of that array into your pointer Type. There are two problems with that.

First, it clobbers the previous value of Type. That 10-character array you just allocated now has nothing pointing to it; you can no longer access it or even deallocate it. This is a memory leak.

This isn't what the compiler is complaining about.

Second, a string literal creates a statically allocated const array ("statically allocated" meaning it exists for the entire execution of your program). Type is not declared with a const qualifier. If the compiler allowed you to point Type to the string "Access", you could use that pointer to (attempt to) modify it:

Type = "Access";
Type[0] = 'a'; // try to change the string to "access"

The purpose of const is to prevent you from modifying, or even attempting to modify, things that are read-only. That's why you're not allowed to assign a non-const pointer value to a const pointer object.

Since you're programming in C++, you're probably better off using std::string.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
5

I want to pass a string via char* to a function.

Here is how you can pass a string via char* to a function (note the required const keyword in the function signature.)

#include <iostream>
void f(const char* p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}

But, what if you are invoking an existing function, and cannot modify its signature?

If you have some external guarantee that the function will not write through its argument pointer,

#include <iostream>
void f(char* p) {
  std::cout << p << "\n";
}

int main() {
  f(const_cast<char*>("Access"));
}

If, on the other hand, the function might write to the string, then you'll need to allocate space for the string:

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the heap
  char *p = new char[strlen("Access"+1)];
  // Copy string to allocated space
  strcpy(p, "Access");
  f(p);
  delete p;
}

or,

#include <iostream>
void f(char* p) {
  *++p;
  std::cout << p << "\n";
}

int main() {
  // Allocate read-write space on the stack
  char arr[] = "Access";
  f(arr);
}

But, the best course by far is to avoid the whole pointer mishegas:

#include <iostream>
void f(const std::string& p) {
  std::cout << p << "\n";
}

int main() {
  f("Access");
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

You've got a basic operations problem here, not a coding issue.

When you want to change the contents of a C char array, you do not use the assignment operator. That will instead change the value of the underlying pointer. Ick.

Instead you are supposed to use the C string library routines. For instance, strcpy (Type, "Access"); will copy the string literal "Access" into your character array, with its all-important trailing nul character.

If you are using C++ (as your tags indicate), you should probably be using std::string instead of arrays of char. Assignment works they way you are expecting there.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134