Strncpy Causing Segmentation Fault c++

342 views Asked by At

I have a c++ program which reads a text file and then converts that text file to a string. Then, it converts the string to a character array using strncpy. I have already seen the stackoverflow question on strncpy and taken the necessary precautions in order to avoid the issues it causes when creating the array. Could someone please explain why it still causes a stack error.

#include <iostream>
#include <string.h>
#include <random>
#include <fstream>
#include <istream>
#include <sstream>
#include <stdio.h>

using namespace std;

int main()
{
    //open a stream reader
    ifstream fin;
    //opens the text file in the stream reader
    fin.open("songlyrics.txt");
    //will be used to aggregate all characters in text file
    string song;
    //used as a pointer when reading each character in text file
    char ch;
    //while the end of file is not reached
    while(!fin.eof())
    {
        //get the character from the file and add it to the song string
        fin.get(ch);
        song += ch;
    }
    //close the file
    fin.close();
    //make a character array called lyrics_ with a length of the length of song
    char lyrics_[song.length()];
    //use strncpy to convert song to a char array, lyrics_
    strncpy(lyrics_, song.c_str(), sizeof(lyrics_));
    //avoid the segmentation fault
    lyrics_[sizeof(lyrics_) - 1] = 0;
    cout<<lyrics_;
    return 0;
}
2

There are 2 answers

5
Barry On BEST ANSWER

This:

char lyrics_[song.length()];
//           ^^^^^^^^^^^^^
//           not a compile-time constant

Is a variable-length array, and is not standard C++.

Also, you don't need to convert a std::string to a character array. It kind of already is:

char* lyrics = &song[0]; // assuming you don't append to song in the future

If you really want a separate character buffer, you'll have to allocate it dynamically:

char* lyrics = new char[song.length() + 1];
memcpy(lyrics, song.c_str(), song.length() + 1); // this will copy the null terminator
delete [] lyrics; // don't forget this
0
jxh On

C++ does not support the variable length array feature from C. VLA was a standard feature of C.1999, and an optional feature in C.2011.

If you want to make a copy of the contents of a string into a dynamically sized array of char, you can use a vector:

std::vector<char> lyrics_(song.begin(), song.end());
lyrics_.push_back('\0');
std::cout << &lyrics_[0];