Question

I have a problem, do not to compile this code but, to execute this program. When I run it in the terminal it prints the first 2 cout then the program stops working and the screen on the windows that tells you, i think the problem is to strcat. I'm using DEVC++ and I have windows 7 pro.

#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>

using namespace std;

int main() {

    char* cambia[] = {"ciao "};
    char* c[] = {"mondo"};

    cout << "*c: " << *c << endl;
    cout << "*cambia: " << *cambia << endl;

    strcat( *cambia, *c );
    cout << "*cambia: " << *cambia << endl;
}
Was it helpful?

Solution

You don't use strcat() in C++ if you don't absolutely have to (e.g. when maintaining legacy code and touching as little stuff as possible).

Use std::string and its member functions like find or substr for simple tasks, string streams or Boost libraries for more complex string splitting.

At any rate, stay away from strcat().

OTHER TIPS

The method strcat() adds the string from the second argument to the buffer of which you submit to the first argument.

First, the buffer has to be writable. In your example, you are passing a string literal as buffer. Naturally, string literals are read-only. But even then, the string literal has no spare space where the new string could be added.

Instead of fixing your code, let me show you some proper examples how to concat strings in C++ and in C.

This example is showing you how to concat two C++ strings:

#include <iostream>
#include <string>

int main(int argc, const char * argv[])
{
    // Create a new C++ string with an initial text.
    std::string result = "First string part ";
    std::cout << "Result: " << result << std::endl;

    // Add some text
    std::string textToAppend = "and the second part";
    result.append(textToAppend);
    std::cout << "Result: " << result << std::endl;

    return 0;
}

The following example is showing you how to concat two strings in C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main(int argc, const char * argv[])
{
    // The two texts to concat
    const char *firstText = "This is the first text ";
    const char *secondText = "and this is the second one";

    // A buffer which is large enough for the operation.
    const int bufferSize = 1024;
    char buffer[bufferSize];

    // Copy the initial text into the buffer.
    strncpy(buffer, firstText, bufferSize);

    // Add the secon string
    strncat(buffer, secondText, bufferSize-strlen(buffer));

    // Output the string
    printf("Result: %s\n", buffer);

    return 0;
}

I suggest, you should use C++ strings if possible. They automatically manage the memory which prevent many memory related issues with C strings.

This line

 char* cambia[] = {"ciao "};

creates a variable named cambia in a dynamically created part of memory, called 'stack'. The variable is an array with no declared size, and elements of that array are pointers to characters.

The size of the array follows from the initializer

{"ciao "}

which implies the array will have only one element, and that element is initialized with a value pointing at the first character of string "ciao ". However, the string "ciao " is placed in some completely different area of memory - it is in static block, initialized by a compiler with values found in the program's code. Compiler does not know how you use these values, in particular it doesn't know you will extend it with strcat, so it will not reserve any additional space after the string.

As a result when you concatenate "mondo" to "ciao ", you overwrite some data in memory, possibly some important data...

I'd suggest you to declare local variables for your string, with explicit size:

char cambia[ 20] = "ciao ";
char c[] = "mondo";

This will make a cambia variable long enough to keep 19-character string (plus implicit terminating zero byte '\0', ASCII NUL) and initialize its first 6 bytes with letters 'c', 'i', 'a', 'o', a space ' ' and NUL. Variable c is implicitly sized to 6 (the initializing string length 5 plus 1 for terminating NUL).

Then you can safely concatenate

strcat( cambia, c);

to obtain 11-character string "ciao mondo" and print it out

cout <<"cambia: "<<cambia<<endl;

The problem here is that you are trying to write to a read-only string storage.

These declarations:

char* cambia[] = {"ciao "};
char* c[] = {"mondo"};

declare two arrays, each with a constant string member. The "ciao " and "mondo" are located in read-only memory.

So when you call strcat(*cambia, *c), you are trying to write "mondo" onto the end of "ciao ". Not only does this write to read-only memory, but it also writes outside the memory space given for the string - there is only space for 6 char in the "ciao " string, and you are trying to add another 5 to the end of that.

The solution is to reserve some space for each string. There are various ways to do this. Here's a simple one:

char acambia[20] = "ciao ";     // Space for 20 characters. 
char* cambia[] = { acambia };

Of coruse, not using the extra level of indirection would make it simpler:

char cambia[20] = "ciao ";
char c[] = "mondo";

strcat(cambia, c); 

would achieve the correct result.

First of all you need not headers

#include <string>
#include <cstdlib>

because neither declaration from them is used.

Aslo header

#include <string.h>

should be substituted for

#include <cstring>

In these statements

char* cambia[] = {"ciao "};
char* c[] = {"mondo"};

you defined two arrays each of them having one element of type const char *. The compiler should issue either an error or a warning because these definitions are not correct. It would be correctly to define the arrays the following way

const char* cambia[] = {"ciao "};
const char* c[] = {"mondo"};

These two statements define arrays of const pointers to string literals. It is undefined behaviour if there ia an attempt to change a string literal in a program. Programs are allowed to place string literals in a read-only memory.

You are right saying that the main problem is in statement

strcat( *cambia, *c );

Function strcat appends one character array to the end of another character array. So the second cjaracter array must reserve enough memory that accomodates the appended character array. If you even would define correctly array cambia as

char cambia[] = {"ciao "};

it had no enough memory to store also characters of array c. So before using strcat you need to reserve enough memory where the concatenated result array would be placed.

You could do this for example the following way

char s[11];

strcpy( s, *cambia );
strcat( s, c );
cout << "s: " << s << endl;

Take into account that instead of character arrays you could use objects of standard class std::string

In this case to append one string to another is made very simply. For example

std::string cambia = "ciao ";
std::string c = "mondo";

cambia += c;

Or

cambia.append( c );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top