How to fix 'std::logic_error' what(): basic_string::_M_construct null not valid error?
The problem is the two return 0;
statements in your function. The function returns a std::string
, which has no constructors that accept an int
as input. But, it does have a constructor that accepts a const char *
pointer, which 0 is implicitly convertible to. However, constructing a std::string
with a null char *
pointer is undefined behavior, and your implementation has chosen to throw a std::logic_error
exception that you are not catching in your code.
In this case, I would simply return a blank string instead:
std::string myfunc(const std::string &input){
if (input.empty()) return "";
for (int i = 0; i < input.size(); ++i){
char ch = input[i];
if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return "";
}
return input;
}
The caller can then check if the return value is empty, if it wants to:
if (myfunc(input).empty())
// error, do something
else
// OK, do something else
Which would be better served with a function that returns a bool
instead of a std::string
:
bool isvalid(const std::string &input){
if (input.empty()) return false;
for (int i = 0; i < input.size(); ++i){
char ch = input[i];
if ( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) ) return false;
}
return true;
}
// if you still needed this function for something...
std::string myfunc(const std::string &input){
if (!isvalid(input)) return "";
return input;
}
if (!isvalid(input))
// error, do something
else
// OK, do something else
Why does it show terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_S_construct null not valid
In short: You are trying to initialize your arrays with 0, which is a nullptr. So you are actually trying to initialize your first string in the array with a nullptr.
Let's examine
string patient_name[NUM_PATIENTS] = { 0 };
- It defines an old style C array of
NUM_PATIENT
strings. - It initializes this array with
{ 0 }
. - ... which means, the first string get's initalized with
0
, the rest of the strings get default-initialized. - ... which means, the first string in the array is initialized thus:
string(0)
, which is similar tostring(nullptr)
- which probably leads to your exceptionstring::_S_construct null not valid
Actually all your attempts at initalizing are wrong.
You don't need to write = {0}
for the patient_name[NUM_PATIENT]
array at all, because the strings in this array are "default-initialized". They know how initialize themselves to an empty string.string patient_name[NUM_PATIENT];
is enough.
But your other arrays don't get properly initialized at all. = {0}
will initialize the first element of your vector. The remaining elements are "default" initialized (for classes) or not initialized at all (for doubles).
Don't use patient_name[NUM_PATIENT]
at all. Get a better textbook. This is an old-style C array. Use std::vector
(best) or std::array
(better).
Much better would be this:
std::vector<string> patient_names;
std::vector<double> medication...
for (size_t i=0; i<NUM_PATIENT; ++i) {
string next_patient;
getline(patients, next_patient);
patient_names.emplace_back(next_patient);
...
or, to stick close to the text book:
std::vector<string> patient_name(NUM_PATIENTS);
...
while (count<NUM_PATIENTS) {
getline(patients, patient_name[count]);
How to fix terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid exception?
You're trying to initialize an std::string
with 0
. std::string
doesn't have a ctor that takes just an int
, but it does have one that takes a pointer, and an integer literal 0
can convert implicitly to a pointer--specifically, a null pointer.
But, when you pass a pointer to initialize an std::string
, it's required to be a non-null pointer, so passing zero breaks things (and the error message you're getting is telling you that you've tried to break it).
My advice would be to get rid of your: DEFAULT_NODE_VALUE
, and instead provide a default argument to value initialize the item in the node:
node(T a = T()):val(a){}
In which case, it'll work about as it previously did for things like node<int>
, but will also work correctly for types that can't be initialized from 0
. This also gets rid of the ugly DEFAULT_NODE_VALUE
in the client code.
how to fix terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
TL;DR:
Change
std::string i = 0;
and friends to
std::string i;
This will produce empty strings. While you are at it, consider giving the string a meaningful identifier like input
or yes_no
. This will likely help a lot when debugging later and descriptive code greatly reduces the need for comments.
The problem:
std::string i = 0;
and friends.
Why it is a problem:
This is an initialization so a constructor is called.
std::string
doesn't have a constructor that can convert an integer, but it does have a constructor that will take a pointer to a character array and unfortunately an integer literal of 0 looks enough like the old definition of a NULL
pointer
#define NULL 0
to call it rather than emit a compiler error.
Constructing a std::string
with a NULL pointer is pretty much instantly fatal, so the string
constructor traps it and throws an exception.
std::string i = 1;
does not have this problem. The compiler instantly rejects it because there is no historical equivalency between 1 and a pointer or anything else that can be used to initialize a string
.
Side note:
Later in the code watch out for checkforwinner (int*gameBoard)
. It looks like the return type is missing. You'll need to fix this because the program is not running as expected.
There could be a compiler warning for that. If there is, don't ignore warnings. They are the first line of defense against logic errors, so if anything you want to see MORE warnings so that you can fix them before they become harder-to-diagnose runtime problems. Check your compiler documentation for how to turn up the warning level and then crank it up LOUD!
Why does the below code give 'std::logic_error' what(): basic_string::_M_construct null not valid?
The problem is caused by
return true;
in sort_string
. It needs to be
return false;
When you reach that line, xy
is equal to yx
. Hence yx < xy
is false
, not true
.
The line
return xy >= yx;
works because that line is the same as
return yx < xy;
Related Topics
How to Install (V142) Build Tools in Visual Studio
Why Aren't Variable-Length Arrays Part of the C++ Standard
What Are Forward Declarations in C++
Difference Between 'Struct' and 'Typedef Struct' in C++
Why Does Reading a Record Struct Fields from Std::Istream Fail, and How to Fix It
What Are the Evaluation Order Guarantees Introduced by C++17
Where Are Static Variables Stored in C and C++
Std::Enable_If to Conditionally Compile a Member Function
Unresolved External Symbol on Static Class Members
C++ Sorting and Keeping Track of Indexes
C++ - Initializing Variables in Header VS With Constructor
What Is Array to Pointer Decay
What Does the Explicit Keyword Mean
Derived Template-Class Access to Base-Class Member-Data