Executable compiled with MinGW outputs nothing when using vector - c++

I'm new to using MinGW and C++ in general, and whenever try compile my source file, the executable seemingly does nothing, even though it should output a simple "Hello World!". I've tried commenting out the lines that use vector, and it'd output "Hello World!" just fine.
Source code which doesn't seem to do or output anything:
#include <iostream>
#include <vector>
typedef long long ll;
using namespace std;
const int LIMIT = 1000000; // one million
int main(int argc, char *argv[])
{
int* arr = new int[LIMIT] {0};
vector<int>* v = new vector<int>();
cout << "Hello World!" << endl;
delete v;
return 0;
}
Source code with vector commented out that outputs "Hello World!" just fine:
#include <iostream>
#include <vector>
typedef long long ll;
using namespace std;
const int LIMIT = 1000000; // one million
int main(int argc, char *argv[])
{
int* arr = new int[LIMIT] {0};
// vector<int>* v = new vector<int>();
cout << "Hello World!" << endl;
// delete v;
return 0;
}
Both are compiled and run with:
C:\Users\User\my\directory\src> g++ source.cpp -o source.exe -std=c++11
C:\Users\User\my\directory\src> ./source.exe
Compiling and running either doesn't produce any error message. Note that #include <vector> remains uncommented in both instances.

Related

Segmentation fault in C++ adding item to a vector

Lately I have set myself to learn C++, and while working on a bigger project, I have tried to use 'vectors'. But every-time I try passing it a value, it exits with a segmentation fault.
Here is my terminal output:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> test;
cout << "hello world" << endl;
test[0] = 0;
return 0;
}
me#my-MacBook-Pro Desktop % g++ test.cpp -o o && ./o
hello world
zsh: segmentation fault ./o
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> test;
cout << "hello world" << endl;
//test[0] = 0;
return 0;
}
me#my-MacBook-Pro Desktop % g++ test.cpp -o o && ./o
hello world
me#my-MacBook-Pro Desktop %
The segfault is because of out of bound access.
you need to set the size in the ctor
vector<int> test(1);
or push_back:
vector<int> test;
test.push_back(0);
Size it vector<int> test = {0,1,2,3,4}; or vector<int> test(5)
But you might want to use push_back in this situation
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> test;
cout << "hello world" << endl;
test.push_back(0);
cout << test[0];
return 0;
}
Basically adds an item at the end.
Can also use maps with the keys be ints if you want to be able to just [] it or leave in spaces (which from what i saw is what your trying to do)
#include <iostream>
#include <unordered_map>
using namespace std;
int main(){
unordered_map<int, int> test;
cout << "hello world" << endl;
test[0] = 0;
cout << test[0];
return 0;
}

Can I use a const char* or std::string variable containing grammar as argument to libfmt?

Hopefully this is a silly question. I have the following code:
#include <iostream>
#include <fmt/format.h>
#include <string>
int main(){
double f = 1.23456789;
std::cout << fmt::format( "Hello {:f} how are you?\n", f ) << "\n";
return 0;
}
And this works as expected --Hello 1.234568 how are you?
But if I want to encapsulate the string passed into fmt::format as a variable, I run into a compiler error:
#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
double f = 1.23456789;
const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
std::cout << fmt::format( m, f ) << "\n";
return 0;
}
However, on MSVC 2022 using #include <format>, this works perfectly...
#include <iostream>
//#include <fmt/format.h>
#include <format>
#include <string>
int main() {
double f = 1.23456789;
const char* m = "Hello {:f} how are you?\n";
std::cout << std::format( m, f ) << "\n";
return 0;
}
Is this possible using libfmt? It appears libfmt wants a constexpr value passed in whereas msvc's <format> evaluates this at runtime. What silly mistake am I making here?
Since libfmt 8.1, you can wrap the format string in fmt::runtime to enable runtime formatting:
#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
double f = 1.23456789;
const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
std::cout << fmt::format(fmt::runtime(m), f ) << "\n";
return 0;
}
You can use fmt::vformat for run-time string
#include <iostream>
#include <fmt/format.h>
#include <string>
int main() {
double f = 1.23456789;
const char* m = "Hello {:f} how are you?\n"; //can't be constexpr, generated at run time
std::cout << fmt::vformat( m, fmt::make_format_args(f)) << "\n";
return 0;
}
Demo
Is this possible using libfmt? It appears libfmt wants a constexpr
value passed in whereas msvc's evaluates this at runtime.
P2216R3 makes std::format only accept compile-time format string. If you want to use run-time format string you need to use std::vformat. I suspect this is just because MSVC has not implemented P2216R3 yet.

why my cpp code can't run?(about char*[])

this is my code
the error is Segmentation fault,and i can't understand why
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char* szword[100];
int i = 0;
do
{
cin >> szword[i];
cout << szword[i];
i++;
}while(strcmp(szword[i - 1], "done"));
cout << i + 1;
return 0;
}
For starters neither declaration from headers <cstdio> and <string> is used in your program. So you should remove these directives
#include <cstdio>
#include <string>
You declared an initialized array with the element type char *. Thus this statement
cin >> szword[i];
invokes undefined behavior because the pointer szword[i] has indeterminate value.
Moreover this call even if the argument of the operator will be correct
cin >> szword[i];
can fail. You should check whether it was successful. And I think there is no great sense to output the string "done".
Also in this statement
cout << i + 1;
you are outputting a value that is greater than the number of inputted strings.
If to use character arrays then your program could look the following way
#include <iostream>
#include <cstring>
int main()
{
const size_t N = 100;
char szword[N][N];
size_t i = 0;
while ( std::cin.getline( szword[i], sizeof( szword[i] ) ) &&
std::strcmp( szword[i], "done" ) != 0 )
{
std::cout << szword[i++] << '\n';
}
std::cout << i << '\n';
return 0;
}
The program output might look like
Hello
World
2
This below code works fine, if you want to use char *, for C++ string you can use the C++ version
C Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
char *tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(strcmp(tmp, "done"));
cout << i + 1;
return 0;
}
C++ Version:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
string tmp;
int i = 0;
do
{
cin >> tmp;
cout << tmp;
i++;
}while(tmp != "done"));
cout << i + 1;
return 0;
}

Cannot push C style strings into std::vector

I'm trying to push some const char* into a vector, but the vector remains unpopulated after performing the operations I would presume to fill it.
Here's my attempt, where dict is my command-line argument.
test.cc
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<const char*> dictionary;
string line;
getline(dict, line);
while(!dict.fail()) {
dictionary.push_back(line.c_str());
getline(dict, line);
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}
dict
Hello
World
Foo
Bar
After compiling this, I get the following output:
dictionary[0] is
dictionary[1] is
dictionary[2] is
dictionary[3] is
However, if I change the dictionary's type to vector and push back line instead of line.c_str(), I get the expected output:
dictionary[0] is Hello
dictionary[1] is World
dictionary[2] is Foo
dictionary[3] is Bar
I'm not terribly familiar with C style strings, so maybe it has something to do with null termination?
You are storing dangling pointers.
std::string::c_str() isn't a pointer to some permanent copy of data — just think, that would be leaked!
Store the std::strings instead.
Your code invokes undefined behavior, because after you do
dictionary.push_back(line.c_str());
On the next line that pointer may get deleted:
getline(dict, line); // line now is a different string
You are pushing into the dictionary pointers that point to the same address and at the last iteration it fills the memory area with an empty string. If you don't care about memory leakage you can try like this:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
using namespace std;
int main(int argc, char **argv)
{
ifstream dict;
size_t dict_size;
dict.open(argv[1]); // Dictionary
vector<char *> dictionary;
while(!dict.fail()) {
string * line = new string();
getline(dict, *line);
if(line->length()>0)
{
dictionary.push_back((char *)line->c_str());
}
}
dict_size = dictionary.size();
for(int i = 0; i < dict_size; i++)
cout << "dictionary[" << i << "] is " << dictionary[i] << endl;
}

writing data from right to left in file?

instead of saving data and then reversing it i wanted to know if there is any function that can save the output to the file directly from right to left?
for example if i have this simple code:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream fout("filepath");
fout<<"stackoverflow");
return 0;
}
instead of having :
stackoverflow
i want to have:
wolfrevokcats
*this example is just an example don't be mad at me :D
You can reverse the string before writing it. That's the only way I know how to do it because you can't write from "right" to "left"
#include <iostream>
#include <string>
#include <algorithm>
int main(int argc, char **argv) {
std::string thing("my thing");
std::reverse(thing.begin(), thing.end());
std::cout << thing << std::endl;
return 0;
}