C++ cout pointer - c++

Hello
Can somebody explain why second cout in func(char *p) doesn't work:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
char *strhex(char *str);
char *func(char *p);
int main()
{
char *ptr;
char *p=strhex("d");
cout<<"main:"<<p<<endl;
cout<<func(p)<<endl;
system("PAUSE");
return 0;
}
char *func(char *p)
{
cout<<"func1:"<<p<<endl;
char buffer[500]="";
char *zbuffer = buffer;
cout<<"func2:"<<p<<endl; ///doesn't work
return zbuffer;
}
char *strhex(char *str)
{
char buffer[500]="";
char *pbuffer = buffer;
int len = strlen( str );
for( int i = 0; i < len ;i++ )
{
itoa(str[i],pbuffer,16);
pbuffer +=2;
};
*pbuffer = '\0';
pbuffer=buffer;
return pbuffer;
}
Edit:
i'm using DEV C++ 4.9.9.2 on Windows

One big problem here is that strhex is returning a pointer to a local variable (buffer[]). This variable goes out of scope at the end of the function, so the return value points at undefined memory contents that can be overwritten at any time.

Your entire code doesn't work. Both functions return pointers to local arrays, which don't point to anything valid after the function returns. That causes undefined behavior. Since the value of p is one of these invalid pointers, you can't depend on it to be anything at any particular time — that memory probably gets overwritten during func(). You need to either new[] and delete[] the appropriate memory or, preferably, use a proper C++ data structure like std::string.

it looks like it is working but the second cout in main is not printing out a value because you are returning an empty buffer.

Adding to others answers:
You need not reset pbuffer to point to the start of the array and then return it's value:
pbuffer=buffer;
return pbuffer;
you can just say
return buffer;
the array name is also a pointer(pointer to the first element of the array.

Related

I'm learning raw pointers before dealing with smart pointers. Is the following code considered bad practice?

Here is the code I wrote. It makes a const char* to uppercase.
First argument is a pointer to a const char* and the second argument is a temp place holder which is allocated in the heap.
#include <cctype>
#include <cstring>
#include <iostream>
void c_strtoupp(const char** c_str, char* _temp)
{
std::strcpy(_temp, *c_str);
for (unsigned int i = 0; i < std::strlen(*c_str) + 1; i++) _temp[i] = static_cast<char>(std::toupper(_temp[i]));
*c_str = _temp;
}
int main()
{
const char** s = new const char*("alexander");
char* _t = new char[std::strlen(*s) + 1];
c_strtoupp(s, _t);
std::cout << *s << '\n';
delete s;
s = nullptr;
delete[] _t;
_t = nullptr;
//std::cin.get(); // to pause console
return 0;
}
Is the following code considered bad practice?
Yes. Bare pointers to dynamic resources are considered a bad practice. Also, calling std::strlen inside a loop condition is bad practice - you can calculate the length once outside the loop and store it in a variable.
You don't need smart pointers either. A good practice is to use std::string to contain a dynamic string.
Also, setting local pointer to null after deleting it is usually, as it is in this case, pointless because it is clear that _t is immediately going to be out of scope anyway.

String declaration initial length when not initialised

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
char a[20];
cout<<strlen(a)<<endl;
return 0;
}
The output of this code is 11.
Why 11? When I have not initialised it.
As stated here: http://en.cppreference.com/w/cpp/string/byte/strlen,
The behavior (of strlen(str)) is undefined if there is no null character in the character array pointed to by str.
The issue you are facing is caused by uninitialized memory. With char a[20]; you are only reserving memory space, but you are not initializing it. Those 20 bytes can have any possible value and you have no guarantees that any of them is set to 0. That causes the unespected return value of the strlen() call, you simply were lucky that the function found a byte set to 0 before it could cause a crash.
To avoid any problem you should initialize your variables before using. For a null terminated sequence of char you can initialize like so:
char a[20] = "";
Or you can use std::string instead:
#include <iostream>
#include <string>
int main() {
std::string a;
std::cout << a.length() << std::endl;
return 0;
}
The output, if you are wondering, is 0.
If you find uninitialized array's length,The behavior is undefined. if you want correct result initialize it. or use this:
int a[20] = {};
or
memset(a,'\0',20) and then after check the length.

Returning char* from function not working

Visual studio c++ shows that "string" on line 24 has one array element, but the top contains all the text that was input by the user. But when I send to PutString(), it disappears. Why?
#include <stdio.h>
void PutString( const char* pChar ){
for( ; *pChar != 0; pChar++ )
{
putchar( *pChar );
}
}
char* GetString(){
char c[100];
int i = 0;
do
{
c[i] = getchar();
}while( c[i++] != '\n' );
c[i] = '\0';
// PutString( c );
return c;
}
void main(){
char* string = GetString();
PutString( string );
}
Because c is a local variable within GetString and you are returning its address, after which it disappears (moves out of scope). That's undefined behaviour - you're not allowed to use stuff that's gone out of scope. In fact, if you run that through gcc, it tells you that quite explicitly:
qq.cpp:9: warning: address of local variable ‘c’ returned
If you want to return non-simple things (such as arrays instead of integers or floats, which make a copy for you) from a function, you need to (for example) dynamically allocate it so that it survives function return. Something like changing:
char c[100];
into:
char *c = malloc (100); // or equivalent 'new'.
(and remembering to free/delete it eventually, of course).
Even though you may see it in the debugger when you return from GetString, it's still not guaranteed as per the standards.
In any case, there's a good chance the next stack manipulation (such as calling PutString) will wipe out the information.
Here's a C++ version that does it the new/delete way:
#include <stdio.h>
void PutString (const char* pChar ){
for (; *pChar != 0; pChar++)
putchar( *pChar );
}
char* GetString (void) {
char *c = new char[100]; // memory behind c will survive ...
int i = 0;
do {
c[i] = getchar();
} while (c[i++] != '\n');
c[i] = '\0';
return c;
} // ... past here ...
int main (void) {
char* string = GetString();
PutString (string);
delete[] string; // ... until here.
return 0;
}
I should also mention that there are probably better way to get line-based input in both C (fgets or see an earlier answer of mine) and C++ (such as the string getline and the char array getline).
You are returning pointer to a variable that is local to the function in GetString(), when the function returns, the space allocated to the variable is reclaimed.
To fix these you can either dynamically allocate space for the character array or declare it as static so that the lifetime of the variable becomes the entire program.
You GetString will not work correctly as the string (char c[100]) is put onto the stack. When the function gets to the return this will be deleted.
Either use malloc or pass into the function the array.

int to string, char* itoa

trying to get ‘sval’ to contain the string “$1” – “$500” for array indexes 0-499. in the following code, however itoa is giving me strange strings in the code below:
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct data_t {
int ival;
char *sval;
} data_t;
void f1(data_t **d);
int main()
{
data_t *d;
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
f1(&d);
}
/* code for function f1 to fill in array begins */
void f1(data_t **d)
{
int i;
char str[5];
for (int i=0; i<500; i++)
{
(*d)[i].ival=i+1;
itoa (i,str,10);
(*d)[i].sval= str;
}
}
it also seems itoa has been depreciated, but that was what i got when i googled int to string
You don't need ltoa, cout should be just fine. Why do you need to keep the number and its string representation in the array? when you do cout << 10 you get "10" on the output, you don't need any conversions of your own
You, on the other hand, do ltoa without allocating any memory for the strings, which is not healthy as you have probably noticed. You use a local variable (the same, for all the 500 array members), which you try to access after you exit the function - a big no-no, its undefined behavior.
And:
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
No. Not only not needed - shouldn't be there at all! When in C++ - use new and delete, never malloc, that's a C function.

How to return a char array created in function?

I've been programming badly for quite a while and I only really just realised. I have previously created many functions that return character strings as char arrays (or at least pointers to them).
The other day someone pointed out that when my functions return the char arrays pointed to by my functions have gone out of scope and I'm essentially now pointing to a random bit of memory (A nasty dangling pointer).
I didn't really notice this for a while because the char arrays when outputted to the console didn't appear to be corrupt (probably because there wasn't time for that data to be overwritten). I did however notice this when I was returning a string buffer (char array) generated by reading the serial port which was frequently corrupt.
So, how best should I do it?
My bad code is as follows:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
char charArray[] = "Some string\n";
char* charPointer = charArray;
return charPointer;
}
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
I understand that I should perhaps allocate memory in the program before calling the function or create a global variable to put the returned string in, but if my called function is used by many different programs when how should it know the size of the buffer being passed into it in advance and when should this memory be deleted?
The following code also doesn't do what I want it to properly:
#include <cstdlib>
#include <iostream>
using namespace std;
void fillArray(char* charPointer){
char charArray[] = "Some string\n"; // Create string
charPointer = charArray; // Not correct, want to fill predefined array with created string
return;
}
int main(int argc, char** argv) {
char predefinedArray[50] = {0};
fillArray(predefinedArray);
cout << predefinedArray;
return 0;
}
I want to fill the array that the pointer parsed points to but this doesnt' happen in the code above.
Also, when should I use the new[] command to create my array? is it needed? and when should I call delete[] on it.
Many thanks for this, its obviously very fundamental but something I've been doing wrong for a while.
The simplest way would be to return a std::string, and if you needed access to the internal char array use std::string::c_str().
#include <iostream>
#include <string>
using namespace std;
string myGoodFunction(){
char charArray[] = "Some string\n";
return string(charArray);
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
If you need to return something other than a char array, remember that pointers can be used as iterators. This allows you to encapsulate an array in a vector or a similar structure:
vector<int> returnInts() {
int someNums[] = { 1, 2, 3, 4 };
return vector<int>(someNums, someNums + 4);
}
You have two options for returning an array in C++. You can fill in pre-allocated memory (good), or allocate your own within the function and return it (bad). The reason that the first is preferred is because it re-enforces proper disposal of allocated memory.
A basic example would look like this:
void fillArray(char* buffer, int sz) {
char text[] = "hello there!";
if (sizeof(text)>sz) {
// overflow! Buffer is too small!
return;
}
for (int n=0;n<sizeof(text);n++) {
buffer[n] = text[n];
}
}
int main() {
char* buffer = new char[30]; // allocates a buffer of 30 bytes.
fillArray(buffer,30);
cout << buffer;
delete [] buffer;
}
/* note that it would be easier to use static memory in this example */
It isn't hard when you think about the problem.
Declare the array as "static" varible and return with its address.
This code works, but causes a warning :
#include <cstdlib>
#include <iostream>
using namespace std;
char* myBadFunction(){
static char charArray[] = "Some string\n"; // insert "static"
// char* charPointer = charArray;
return charArray; // charArray is a pointer to the static array
} // after returning static varibles stay safe
int main(int argc, char** argv) {
cout << myBadFunction();
return 0;
}
"Some string\n" is a string literal and will therefore exist for the lifetime of the program, so the following would be valid:
#include <cstdlib>
#include <iostream>
using namespace std;
char* myGoodFunction(){
char* charPointer = "Some string\n";
return charPointer;
}
int main(int argc, char** argv) {
cout << myGoodFunction();
return 0;
}
Of course this is only useful if the function always returns the same string. If the returned string can vary (generally the case) then you can declare the char array in your function as static and return it's address (as has already been suggested).