Delete and invalid pointer

2019-01-29 14:52发布

问题:

int main()
{
    char* a=new char[20];  
    cin>>a;  
    cout<<" character at 7-th position."<<a[6];  
    delete a+4;  
    cout<<a[0];
    return 0;
}

Input:

1234567894567 

Output:

character at 7-th position.6  
*** glibc detected *** ./test free() invalid pointer:....  

Now I have 3 questions

  1. Is it correct that delete a+4 will only delete the character at a+4?
  2. If answer to previous one is yes then what happens to a[0].We should get the output.
  3. to delete a chunk of memory we should write delete[].But in this case how come all the elements are deleted?

回答1:

There are only three types of pointer values you can pass as the operand of delete:

  1. Null pointer values. They simply get ignored.
  2. A complete scalar (not array) object previously allocated with new, either of:
    • The exact pointer returned by new
    • A pointer to a base subobject of the pointer returned by new, if and only if the base subobject's type has a virtual destructor

Any these pointer values should NEVER ever be passed to scalar delete:

  1. The result of array new or new[] (use delete[] instead)
  2. The result of malloc or any other allocator which is not new
  3. The address of an object with automatic or static storage duration
  4. The address of a member subobject or array element
  5. Uninitialized pointer values
  6. Pointers to already-deleted objects

If you break this rule, you get undefined behavior. That means your program might crash with a nice message that an invalid delete was detected. Or your data might get corrupted, saved in your data files, sent to your boss, shown to the customer, and later you get fired. So don't break the rule.

Your code falls into category "NEVER DO THIS #4".


The reason it works this way is because an implementation can (and most do) track extra information called metadata along with each allocated block. For example, the size of the block, which is pretty important for enabling reuse. There is no metadata for part of a block, and there may not be any way to find the metadata from a pointer into the middle.



回答2:

  1. No. delete is the opposite of new. You essentially delete the same pointer that you get when allocating. Deleting other pointers is undefined, hence your "invalid pointer" error. If you allocated an array, you have to use delete[]. Right now, you are leaking ("not freeing") that memory. So use delete [] a; after you are done.

  2. Not really applicable.

  3. Because that is how C++ works. It is the operation you use to free an array you allocated.

It appears that you want to remove a character from a string, then print the string. If that is what you are after, consider using a std::string and using its remove member function. Regardless, a[0] is a char, not a char*, the latter of which is a C style string. You should

cout << a;

instead.