Wrong knowledge of pointers [duplicate] - c++

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Why does cout print char arrays differently from other arrays?
(4 answers)
Closed 2 years ago.
Currently, I'm trying to understand why I have to use:
std::cout << "&str1:" << &str1 << std::endl;
To get the memory address of:
const char * str1 = "Good Morning";
I expected that:
std::cout << "str1:" << str1 << std::endl;
would do so.
Here is an example:
void charPointerExamples() {
const int * myInt = new int(1);
const char * str1 = "Good Morning";
const char * str2 = str1;
std::cout << "myInt:" << myInt << std::endl;
std::cout << "&str1:" << &str1 << std::endl;
std::cout << "&str2:" << &str2 << std::endl;
std::cout << "str1:" << str1 << std::endl;
std::cout << "str2:" << str2 << std::endl;
std::cout << "*str1:" << *str1 << std::endl;
std::cout << "*str2:" << *str2 << std::endl;
delete myInt;
}
The output itself:
myInt:0081D450
&str1:003CFD20
&str2:003CFD14
str1:Good Morning
str2:Good Morning
*str1:G
*str2:G

Related

output to screen terminates when I try to access array in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 12 months ago.
I'm trying to return a pointer, that points to an array of strings, from a function and then access elements in the array that the returned pointer points to. I seem to get a pointer back from the function, but when I try to output individual elements of the array to the computer screen, my program seems to just stop outputting and end the program.
Running the code below, the pointer to the array outputs as expected (see screen output screenshot). However, when I try to access the array's elements, none of the elements are output to the screen and the program just ends. Any ideas/thoughts would be greatly appreciated. FYI, I realize that I'm not using the data that's being passed to the function, but that's because I'm trying to figure out how to access the data that gets returned first.
roster.h
#ifndef ROSTER_H
#define ROSTER_H
#include <iostream>
#include <string>
class Roster {
public:
std::string* parseData(const std::string Data);
};
#endif
roster.cpp
#include <iostream>
#include <string>
#include "roster.h"
std::string* Roster::parseData(const std::string Data) {
std::string stringData[3] = { "abc", "def", "ghi" };
return stringData;
}
rostertest.cpp
#include <iostream>
#include <string>
#include "roster.h"
void rosterClassTest()
{
Roster roster;
std::string* returnData = roster.parseData("red,blue,black,gray");
std::cout << "pointer returned: "
<< returnData << std::endl << std::endl;
std::cout << "element 0 of array: "
<< returnData[0] << std::endl << std::endl;
std::cout << "element 1 of array: "
<< returnData[1] << std::endl << std::endl;
std::cout << "element 2 of array: "
<< returnData[2] << std::endl << std::endl;
}
Roster::parseData() is returning a pointer to a local array variable that goes out of scope upon exit, destroying the array, and thus the function is returning a dangling pointer to invalid memory.
You should return a std::vector<std::string> (or std::array<std::string, 3>) instead, eg:
std::vector<std::string> Roster::parseData(const std::string Data) {
std::vector<std::string> stringData{ "abc", "def", "ghi" };
return stringData;
}
std::vector<std::string> returnData = roster.parseData("red,blue,black,gray");
std::cout << "pointer returned: " << returnData.data() << std::endl << std::endl;
for(size_t i = 0; i < returnData.size(); ++i) {
std::cout << "element " << i << " of array: " << returnData[i] << std::endl << std::endl;
}
If that is not an option, then you will have to new[] the array, and then the caller will have to delete[] the array when finished using it, eg:
std::string* Roster::parseData(const std::string Data) {
std::string *stringData = new std::string[3];
stringData[0] = "abc";
stringData[1] = "def";
stringData[2] = "ghi";
return stringData;
}
std::string* returnData = roster.parseData("red,blue,black,gray");
std::cout << "pointer returned: " << returnData << std::endl << std::endl;
std::cout << "element 0 of array: " << returnData[0] << std::endl << std::endl;
std::cout << "element 1 of array: " << returnData[1] << std::endl << std::endl;
std::cout << "element 2 of array: " << returnData[2] << std::endl << std::endl;
delete[] returnData;
In which case, you should return a std::unique_ptr instead, eg:
std::unique_ptr<std::string[]> Roster::parseData(const std::string Data) {
//std::unique_ptr<std::string[]> stringData(new std::string[3]);
auto stringData = std::make_unique<std::string[]>(3);
stringData[0] = "abc";
stringData[1] = "def";
stringData[2] = "ghi";
return stringData;
}
auto returnData = roster.parseData("red,blue,black,gray");
std::cout << "pointer returned: " << returnData.get() << std::endl << std::endl;
std::cout << "element 0 of array: " << returnData[0] << std::endl << std::endl;
std::cout << "element 1 of array: " << returnData[1] << std::endl << std::endl;
std::cout << "element 2 of array: " << returnData[2] << std::endl << std::endl;

C++ Why numeric limits doesn't work for uint8_t and int8_t? [duplicate]

This question already has answers here:
cout not printing unsigned char
(5 answers)
Closed 2 years ago.
I recently noticed numeric_limits::max() and numeric_limits::min() don't seem to work for uint8_t and int8_t. Is there a reason for this or could it be a bug? I tried on my own computer using gcc compiler:
#include <iostream>
#include <limits>
using namespace std;
int main()
{
std::cout << "numeric_limits<uint8_t>::max() = " << numeric_limits<uint8_t>::max() << std::endl;
std::cout << "numeric_limits<int8_t>::max() = " << numeric_limits<int8_t>::max() << std::endl;
std::cout << "numeric_limits<int8_t>::min() = " << numeric_limits<int8_t>::min() << std::endl;
std::cout << "numeric_limits<uint16_t>::max() = " << numeric_limits<uint16_t>::max() << std::endl;
std::cout << "numeric_limits<int16_t>::max() = " << numeric_limits<int16_t>::max() << std::endl;
std::cout << "numeric_limits<int16_t>::min() = " << numeric_limits<int16_t>::min() << std::endl;
std::cout << "numeric_limits<uint32_t>::max() = " << numeric_limits<uint32_t>::max() << std::endl;
std::cout << "numeric_limits<int32_t>::max() = " << numeric_limits<int32_t>::max() << std::endl;
std::cout << "numeric_limits<int32_t>::min() = " << numeric_limits<int32_t>::min() << std::endl;
std::cout << "numeric_limits<uint64_t>::max() = " << numeric_limits<uint64_t>::max() << std::endl;
std::cout << "numeric_limits<int64_t>::max() = " << numeric_limits<int64_t>::max() << std::endl;
std::cout << "numeric_limits<int64_t>::min() = " << numeric_limits<int64_t>::min() << std::endl;
return 0;
}
gives output:
numeric_limits<uint8_t>::max() = �
numeric_limits<int8_t>::max() =
numeric_limits<int8_t>::min() = �
numeric_limits<uint16_t>::max() = 65535
numeric_limits<int16_t>::max() = 32767
numeric_limits<int16_t>::min() = -32768
numeric_limits<uint32_t>::max() = 4294967295
numeric_limits<int32_t>::max() = 2147483647
numeric_limits<int32_t>::min() = -2147483648
numeric_limits<uint64_t>::max() = 18446744073709551615
numeric_limits<int64_t>::max() = 9223372036854775807
numeric_limits<int64_t>::min() = -9223372036854775808
It does work. The output is interpreted as ASCII characters though. If you cast to int before you print, you will see the correct values:
std::cout << "numeric_limits<uint8_t>::max() = " << static_cast<int>(numeric_limits<uint8_t>::max()) << std::endl;
std::cout << "numeric_limits<int8_t>::max() = " << static_cast<int>(numeric_limits<int8_t>::max()) << std::endl;
std::cout << "numeric_limits<int8_t>::min() = " << static_cast<int>(numeric_limits<int8_t>::min()) << std::endl;
std::cout << "numeric_limits<uint8_t>::max() = " << std::to_string(numeric_limits<uint8_t>::max()) << std::endl;
std::cout << "numeric_limits<int8_t>::max() = " << std::to_string(numeric_limits<int8_t>::max()) << std::endl;
std::cout << "numeric_limits<int8_t>::min() = " << std::to_string(numeric_limits<int8_t>::min()) << std::endl;
try to convert them to string, before inserting them into cout.
int8 types are probably defined as chars, so don't print the values as charbut as ints:
int main() {
std::cout << "numeric_limits<uint8_t>::max() = " << (int)numeric_limits<uint8_t>::max() << std::endl;
std::cout << "numeric_limits<int8_t>::max() = " << (int)numeric_limits<int8_t>::max() << std::endl;
std::cout << "numeric_limits<int8_t>::min() = " << (int)numeric_limits<int8_t>::min() << std::endl;
}

C++: Convert string or char to int [duplicate]

This question already has answers here:
How can I convert a std::string to int?
(24 answers)
Closed 2 years ago.
If I have:
string number = "45";
How do I turn "45" into 45 as an integer?
I want to be able to do this:
string number + 20 = 65
You can use the following example from https://en.cppreference.com/w/cpp/string/basic_string/stol:
#include <iostream>
#include <string>
int main()
{
std::string str1 = "45";
std::string str2 = "3.14159";
std::string str3 = "31337 with words";
std::string str4 = "words and 2";
int myint1 = std::stoi(str1);
int myint2 = std::stoi(str2);
int myint3 = std::stoi(str3);
// error: 'std::invalid_argument'
// int myint4 = std::stoi(str4);
std::cout << "std::stoi(\"" << str1 << "\") is " << myint1 << '\n';
std::cout << "std::stoi(\"" << str2 << "\") is " << myint2 << '\n';
std::cout << "std::stoi(\"" << str3 << "\") is " << myint3 << '\n';
//std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';
}

stoi is not declared in this scope? [duplicate]

This question already has answers here:
Function stoi not declared
(13 answers)
Closed 8 years ago.
I am trying to convert a string into int using stoi() but i am getting error that error: ‘stoi’ was not declared in this scope. Here is the given code.
#include <iostream>
#include <string>
int main()
{
std::string str1 = "45";
std::string str2 = "3.14159";
std::string str3 = "31337 with words";
std::string str4 = "words and 2";
int myint1 = std::stoi(str1);
int myint2 = std::stoi(str2);
int myint3 = std::stoi(str3);
// error: 'std::invalid_argument'
// int myint4 = std::stoi(str4);
std::cout << "std::stoi(\"" << str1 << "\") is " << myint1 << '\n';
std::cout << "std::stoi(\"" << str2 << "\") is " << myint2 << '\n';
std::cout << "std::stoi(\"" << str3 << "\") is " << myint3 << '\n';
//std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';
}
stoi is from C++11, you should try with atoi

Why does a nullptr terminated array passed to function through ***char loose the termination element? [duplicate]

This question already has answers here:
Passing a char pointer array to a function
(2 answers)
Closed 8 years ago.
Note 1: I am not looking for different solutions to the problem at hand. I'm curious about what actually is happening here.
Note 2: I'm doing this in c++ context, but am assuming that this also applies to C, hence the C tag. (apart from the representation of a null pointer)
This is about c-strings and access to original from a function. I'll use argv and argc to illustrate that the array should be nullptr terminated. I declare them like this:
int argc = 1;
char **argv = (char**) malloc( (argc + 1) * sizeof(char*) );
argv[0] = (char*)"argument 0";
argv[1] = nullptr;
If I declare a function like this: func1(int &f_argc, char **f_argv) I can access all elements inside the function scope, including f_argv[f_argc], which is nullptr, but I cannot modify the original argv to point to a different address as f_argv in the function is a value passed copy of the original pointer. It has a different address in memory.
If I declare the function like this instead: func2(int &f_argc, char ***f_argv), I can access the original argv through *f_argv in the function, but the last element (which should be nullptr) is cut off. This means that if I try to check for the terminating nullptr inside the function, I try to access an element outside the range of the array, resulting in a core dump at runtime.
Q1: Why is f_argv cut off when reaching the nullptr in func2, but not in func1?
Q2: Is there a way to get write access to the original argv from within the function, without removing the terminator?
Edit: (added code to show what I mean)
#include <iostream>
#include <cstring>
void func1(int &f_argc, char **f_argv) {
using std::cout;
using std::endl;
cout << " In function:" << endl;
cout << " argv passed as **f_argv" << endl;
cout << " f_argv = " << f_argv << " , &f_argv = " << &f_argv << endl;
for (int pos = 0; pos < f_argc; pos++) {
if (f_argv[pos] != nullptr) {
cout << " f_argv[" << pos << "] = \"" << f_argv[pos] << "\"" << endl;
} else {
cout << " f_argv is prematurely terminated" << endl;
}
}
if (f_argv[f_argc] == nullptr) {
cout << " f_argv is correctly terminated" << endl;
} else {
cout << " f_argv[" << f_argc << "] = \"" << f_argv[f_argc] << "\"" << endl;
cout << " f_argv is not terminated" << endl;
}
// Intention is to copy argv here, add elements, terminate it with
// nullptr and change original argv to point to copy. This wouldn't
// work in this function, as &f_argv != &argv.
return;
}
void func2(int &f_argc, char ***f_argv) {
using std::cout;
using std::endl;
cout << " In function:" << endl;
cout << " array passed as ***f_argv" << endl;
cout << " f_argc = " << f_argc
<< " , &f_argc = " << &f_argc << endl;
cout << " *f_argv = " << *f_argv
<< " , f_argv = " << f_argv << endl;
for (int pos = 0; pos < f_argc; pos++) {
cout << " about to check: "
<< "if (*f_argv[" << pos << "] != nullptr)" << endl;
if (*f_argv[pos] != nullptr) {
cout << " *f_argv[" << pos << "] = \""
<< *f_argv[pos] << "\"" << endl;
} else {
cout << " *f_argv is prematurely terminated" << endl;
}
}
if (*f_argv[f_argc] == nullptr) {
cout << " *f_argv is correctly terminated" << endl;
} else {
cout << " *f_argv[" << f_argc << "] = \""
<< *f_argv[f_argc] << "\"" << endl;
cout << " *f_argv is not terminated" << endl;
}
// Intention is to copy argv here, add elements, terminate it with
// nullptr and change original argv to point to copy.
return;
}
// --------------------------------------------
int main() {
using std::cout;
using std::endl;
int argc=1;
char **argv = (char**) malloc( (argc + 1) * sizeof(char*) );
argv[0] = (char*)"argument 0";
argv[1] = nullptr;
cout << "Before function call" << endl;
cout << "argv = " << argv << " , &argv = " << &argv << endl;
for (int i = 0; i < argc; i++) {
if (argv[i] != nullptr) {
cout << "argv[" << i << "] = \"" << argv[i] << "\"" << endl;
} else {
cout << "argv is prematurely terminated" << endl;
}
}
if (argv[argc] == nullptr) {
cout << "argv is correctly terminated" << endl;
} else {
cout << "argv[" << argc << "] = \"" << argv[argc] << "\"" << endl;
cout << "argv is not terminated" << endl;
}
// run one of these
//func1(argc, argv);
func2(argc, &argv);
free(argv);
return 0;
}
If running func2, running the program results in a core dump at this line:
if (*f_argv[f_argc] == nullptr) {
The subscript operator has higher precedence than the dereference operator. *f_argv[f_argc] is *(f_argv[f_argc]). What you want is (*f_argv)[f_argc].
Since you are using C++, you should consider taking f_argv by reference - void f(int &f_argc, char **& f_argv);.