-1

Recently I was deleting an object and an exception would get thrown, and I have narrowed it down to the use of strcpy(). To test this, I made a simple test class that uses (basically) only strcpy() and voila, an exception.

#pragma once
class TestClass
{
public:
    TestClass(char []);
    ~TestClass();

    char teststring[];
};

It's constructor looks like this:

TestClass::TestClass(char incstring[])
{
    strcpy(teststring, incstring);
    printf(teststring);
}

If I run the following code:

int main(){
    TestClass* test = new TestClass("Cheezit");

    delete test;
}

I get a thrown exception! What is HAPPENING WITH STRCPY()??!?!?!?!

Note: The console window does print "Cheezit".

  • 4
    That is not a valid class definition. Your code is not valid C++; you are very unlucky to be using a broken compiler (or using a compiler in a broken way) that it lets you get away with this. – Kerrek SB Apr 19 '17 at 22:14
  • Please edit your question to contain a [mcve] – Slava Apr 19 '17 at 22:15
  • @Slava: it probably is. This looks like a C flexible array member, strangely permitted in C++. – Kerrek SB Apr 19 '17 at 22:15
  • How does it work in C? – Slava Apr 19 '17 at 22:16
  • 1
    @Slava: It's called a "[flexible array member](https://en.wikipedia.org/wiki/Flexible_array_member)". You can only use it in dynamic allocation contexts. – Kerrek SB Apr 19 '17 at 22:16
  • If you are using GCC, add the -pedantic flag. Also, I really doubt that an exception is being thrown. You are almost certainly getting a segmentation fault or something similar - these are not exceptions in the C++ sense. –  Apr 19 '17 at 22:18
  • 1
    The code is not a MCVE, since it lacks the needed `#include`s and the definition of `~TestClass`. – aschepler Apr 19 '17 at 22:20
  • The problem is not `strcpy`, the problem is that you write to `test->teststring` which doesn't have memory to hold `"Cheezit"`. – nwp Apr 19 '17 at 22:21
  • 2
    Does not compile on gcc http://ideone.com/Z1JY2J – Slava Apr 19 '17 at 22:21

2 Answers2

2

Your code is not valid C++. In C++, all non-static class data members must have complete type, and char[] is not a complete type. You need to specify the array size, and then initialize the array accordingly:

class TestClass
{
public:
    TestClass(char a[]) : teststring{} { std::strncpy(teststring, a, 2); }
    char teststring[3];
};

You cannot deduce the array size from any constructor, because the constructor is part of the class, and the class is not complete until the array size has been specified.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • With C++17 he could make it a template class and have the size deduced: http://en.cppreference.com/w/cpp/language/class_template_deduction – Jerry Jeremiah Apr 19 '17 at 22:34
  • @JerryJeremiah: Sure, but that's something completely different... (And you wouldn't deduce of a constructor parameter *value*!) – Kerrek SB Apr 19 '17 at 22:36
  • @KerrekSB thank you, I have since changed teststring to a char pointer (char*) and in TestClass's constructor I have a line just before strcpy() that reads: "teststring = new char[sizeof(incstring)];". Will this make teststring point to an array the size of incstring? and is this memory safe? – Daniel Oelbaum Apr 20 '17 at 16:13
  • 1
    @DanielOelbaum: It is none of these things. Every single thing you said has a bug in it. Update your question and I can point them out. Or just look on this website, search for "array size" and "sizeof". And look up how null-terminated strings work and how `strcpy` works. – Kerrek SB Apr 20 '17 at 19:10
  • I did some research and think I have made some progress. I have posted another question at http://stackoverflow.com/questions/43531933/using-passed-in-array-to-initialize-other-array. if any of you could help me out there, I would appreciate it greatly – Daniel Oelbaum Apr 21 '17 at 00:19
  • @DanielOelbaum: Yeah, I saw... to be honest, there is just *so much* wrong with that code, it's really hard to point out in a brief answer. I could probably spend a whole hour dissecting that code... maybe someone will post a longer review answer. – Kerrek SB Apr 21 '17 at 00:21
1
char teststring[];

as an array member is not allowed in Standard C++.

Your compiler appears to be treating it as a Flexible Array Member, a feature from C, as an extension to C++. However, using a Flexible Array Member correctly requires some care with allocation, which you have not done. So even supposing there is some such extension, your program still has undefined behavior.

aschepler
  • 70,891
  • 9
  • 107
  • 161