Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with this code?

Tags:

c++

int main()
{
    char *name = new char[7];
    name = "Dolphin";
    cout << "Your name is : " << name <<endl;
    delete [] name;
}

Why doesn't the VC++ compiler complain?

like image 653
Sam Avatar asked Nov 28 '22 06:11

Sam


2 Answers

You've got two questions here:

First, What's wrong with code? Well ...

When you assign "Dolphin" to name you are not copying into the allocated array you are adjusting the pointer to point to a string literal. Later you try to delete what the pointer points to. I'd expect this to crash horribly in some environments.

If you really want a copy of the "Dolphin" characters, have a look at strncpy(), but as already been observed, you need a space for the null too.

Second, why that particular compiler doesn't warn you that the assignment is potentially: that's a bit harder. [It's been observed that other compilers will give a warning.] The question is whether this compiler treats a string literal as a "Pointer to const char" or a "Pointer to char".

If it was the former case then I'd expect an error. Until about 2004 C++ was consistent with C in treating literals as pointer to char, and hence the assignment would be permitted. So I guess the question for you is to determine what version of the specs you are working against, and that might depend upon the version of VC++ you are using and also any compiler options you have chosen.

A MSDN C++ reference indicates that VC++ treats string literals as non const. I'll leave it to VC++ gurus to comment further.

like image 144
djna Avatar answered Dec 20 '22 01:12

djna


This line is bad:

name = "Dolphin";

That is not copying a string but reassigning the pointer.

So this causes two problems.

  1. You are freeing non allocated memory here delete [] name; because you are trying to free the pointer to the literal string "Dolphin"
  2. The memory allocated in char *name = new char[7]; is leaked.

Since this is C++ you should just use std::string. No need to manually allocate or deallocate and then you get value semantics:

int main()
{
    std::string name;
    name = "Dolphin";
    cout << "Your name is : " << name <<endl;
}

Finally, if you are trying to understand raw pointers better, here is a version of your code that will work correctly. The important things to note is that the code allocates the length+1 (the extra +1 is for the terminating NUL byte) and uses strcpy to copy the data into the newly allocated memory:

char *strdup_via_new(const char *str)
{
    char *tmp = new char[strlen(str) + 1];
    strcpy(tmp, str);
    return tmp;
}

int main()
{
    char *name = strdup_via_new("Dolphin");
    cout << "Your name is : " << name <<endl;
    delete [] name;
}
like image 37
R Samuel Klatchko Avatar answered Dec 20 '22 01:12

R Samuel Klatchko