Pointer Failure (C++) [duplicate] - c++

This question already exists:
Closed 11 years ago.
Possible Duplicate:
c++ warning: address of local variable
char* strdup(const char* s)
{
char dup[strlen(s)];
for (int i = 0; i<strlen(s); i++)
{
dup[i]=s[i];
}
return dup;
}
This function is supposed to hold the new array that has been read backwards plus another slot. When I compile it I get the error "warning: address of local variable 'dup' returned" and when I run the program it returns the memory address.

char dup[strlen(s)] defines a local stack variable; this goes out of scope when the function ends, so any attempt to access it after that will result in undefined behaviour.
Your options are:
Use a heap variable (obtained using new). You will have to remember to delete it at some point.
Have the function write into an existing buffer, provided by the caller (e.g. void strdup(char *out, const char *in)).
Use C++ constructs like std::string, which do all the hard work for you.
As you have marked your question "C++", I strongly recommend Option #3.

Your definition specifies an char array pointer as its return type but you initialize a char array inside your function and try to return it. Try this:
char* strdup(const char* s)
{
char *dup = new char[strlen(s)];
for (int i = 0; i<strlen(s); i++)
{
dup[i]=s[i];
}
return dup;
}

The problem is that you never allocate dup on the heap, so when you exit the stack frame, dup will automatically be removed with the stack frame. This means that it's not possible to have a valid reference to dup, as it ceases to exist once you exit the function.

This should work:
char* strdup(const char* s)
{
char* dup = new char[strlen(s)];
for (int i = 0; i<strlen(s); i++)
{
dup[i]=s[i];
}
return dup;
}
EDIT: when you are done, don't forget to use 'delete' to free the memory ;)

you can't return dup[] because, as it is, it's a local variable and won't be valid outside the function (well, the memory it points to won't be valid anymore). You have to call something like malloc(), which allocates memory on the heap (space visible by all your app)

char* strdup(const char* s)
{
char dup[strlen(s)]; // defines *local* variable on *stack*
for (int i = 0; i<strlen(s); i++)
{
dup[i]=s[i];
}
return dup; // returning dup[0] = dup address
}
You are returning address of local variable, created on stack. When you return from the function the stack will be rewind and your dup variable gone.

The line
char dup[strlen(s)];
will not work in C++. Arrays need a constant size specified at compile time; strlen(s) is a variable.
As far as your actual warning is concerned, it is a bad practice to return a pointer to a local variable to the caller; since the local variable (in this case, the array dup) is allocated on the stack, when the function returns, it is deallocated, and hence, the returned pointer may be invalid. Compilers are designed to catch such errors and flag a warning saying that this could be a potential source of problems.

The dup variable is an array of char and is allocated on the stack rather than the heap (via new or malloc). As soon as the stack frame is left (that is: the function is left) this is undefined memory that will be overwritten by other things soon.
You need to turn dup into a char * and use new or malloc to allocate the necessary memory.

Related

c++ code block ok but still get not compile

int* areaofsquare(int len,int width){
int value = len*width;
return &value;
}
int main() {
printf("area=%i\n",*areaofsquare(1,2));
return 0;
}
Why I get memory error from this code? As per my understanding I did not get any error in this code block so why does it not run properly?
Help me out.
Thank you.
You can't just return pointer to stack variable, as it's getting invalidated as the function returns. You can use dynamic memory allocation instead:
int* area(int leangth,int width){
int * area = malloc(sizeof(int));
*area = leangth*width;
return area;
}
int main() {
printf("area=%i\n",*area(5,6));
}
Please note that you create memory leak and it would be better to handle it some way, but in this tiny example it doesn't matter.
You are returning the address of a local function variable in your function area. When the function returns, its stack space is no longer valid, so attempting to access an address to a local variable from that function is undefined behavior.
I don't see why you need to make area return a pointer to an int. Just return area's value and have area's return type just be int instead.
If for some reason you are required to return a pointer to an int (i.e. assignment or deliverable specifications), you have some options:
Use heap memory. Allocate area with malloc, and free it in main after you've printed its value.
Use static to put area into the process' data section rather than in stack memory, so that it persists beyond its scope and an address-of operation on it will continue to work after the function returns.

My C program is crashing when I call a method from a class instance here is the code

here is the class that I am using.
#include<stdio.h>
#include <string.h>
class EnDe{
private:
int *k;
char *temp;
public:
char * EncryptString(char *str);
char * DecryptString(char *str);
EnDe(int *key);};
EnDe::EnDe(int *key){
k=key;
}
char * EnDe::EncryptString(char *str){
int t=2;
t=(int)k[1]*(int)2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]+k[0]-k[2]+2-k[1]+k[3]+t;
}
char alp=k[0]*57;
for (int y=strlen(str);y<strlen(str)+9;y++){ //--*
temp[y]=alp+y; //--*
}
temp[(strlen(str)+9)]='\0'; //--*
return temp;
}
char * EnDe::DecryptString(char *str){
int t=2;
t=k[1]*2;
for (int i=0;i<strlen(str);i++){
temp[i]=str[i]-t-k[3]+k[1]-2+k[2]-k[0];
}
temp[(strlen(str)-9)]='\0';
return temp;
}
And here is the main program.
#include <stdio.h>
#include "EnDe.h"
int main(void){
char *enc;
char op;
printf("\nE to encrypt and D to decrypt");
int opi[4]={1,2,9,1};
EnDe en(opi);
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
printf("Encrypted : %s",enc);
return 0;
}
Something is wrong with en.EncryptString function
when I run the program it stops working giving error and on removing strcpy(enc,en.EncryptString("It is C's Lounge!! ")); it runs. I want this problem to be resolved.
char *enc;
strcpy(enc,en.EncryptString("It is C's Lounge!! "));
You don't provide any space for the copy - enc doesn't point anywhere.
You never allocate any memory.
When you say
char *foo;
You tell the compiler that you want to store a memory address to some data somewhere, but not that you also want to store some data. Your class stores two pointers (int *k and char *temp) that never get any memory assigned to them, and so does your main function with char *enc. This can never work.
In C and C++, there are two modes of memory allocation: one is stack-based allocation, where you declare variable names in a function, and the compiler or the runtime will automatically allocate and release memory for you; the other is heap-based allocation, where you use malloc or new to allocate memory at run time, and must manually release that memory again with delete or free.
A pointer is "just" a stack-allocated variable that contains the address of another memory location. If you don't assign any value to a pointer, it points to invalid memory, and whatever you try to do with it will fail. To fix your program, you must make sure that every pointer points to valid memory. If you want it to point to a stack-based variable, you use the address-of operator:
int val = 4;
int *pointer_to_val = &val;
/* the pointer_to_val variable now holds the address of the val variable */
If you don't want it to point to a stack-allocated variable, you must allocate the memory yourself.
In C++, heap memory is allocated with the new operator, like so:
ClassType *instance = new ClassType(arg1, arg2)
where ClassType is the type of the class you're creating an instance of, instance is the pointer where you want to store the address of the instance you've just created, and arg1 and arg2 are arguments to the ClassType constructor that you want to run.
When you no longer need the allocated memory, you use delete to release the memory:
delete instance;
Alternatively, you can also use the C-style malloc and free functions. These are not operators; they are functions which return the address of the allocated memory. They do not work for C++ class instances (since you do not run the constructor over the returned memory), but if you want to run a pure-C program, they're all you have. With malloc, you do as follows:
char* string = malloc(size);
where string is the pointer for which you want to allocate memory, and size is the number of bytes you want the system to allocate for you. Once you're ready using the memory, you release it with free:
free(string);
When calling delete or free, it is not necessary to specify the size of the object (the system remembers that for you). Note, however, that you must make sure to always use delete for memory allocated with new, and to always use free for memory allocated with malloc. Mixing the two will result in undefined behaviour and possibly a crash.

Initialize obj then pass into a function <bad ptr>

I'm trying to initialize the values of an object, then pass it into a function, but visual studio tells me at this point that my two variables (question and answer) inside my object have "bad pointers" and cannot be evaluated. Unfortunately, I need to access both later on.
I've tried displaying question[i] and answer[i] right before calling enqueue() and it echoes correctly.
It's as if when I call the enqueue() function it doesn't remember what values I gave the card object when I called the constructor right before.
I'm not sure why my code breaks here, do I need to make a dynamic object?
card::card(char *q_input, char *a_input)
{
char * question = new char [75];
char * answer = new char [25];
strncpy(question,q_input,strlen(q_input)+1);
strncpy(answer,a_input,strlen(a_input)+1);
}
...
int queue::fill_deck(char **question, char **answer)
{
for(int i = 0; i < 9; i++)
{
card Card(question[i],answer[i]);
enqueue(Card); //ERROR!
}
return 0;
}
Thank you for the help!
Please let me know if you need more information.
EDIT: the problem was that I was redeclaring two variables with my constructor. A syntax mistake on my part!
One huge issue: This code does nothing except cause a memory leak:
card::card(char *q_input, char *a_input)
{
char * question = new char [75];
char * answer = new char [25];
strncpy(question,q_input,strlen(q_input)+1);
strncpy(answer,a_input,strlen(a_input)+1);
}
question and answer are local variables. Not only that, you then allocate memory and assign the returned pointer to these local variables. When that function exits, those locals go away, plus any chance of deallocating the memory you allocated goes away with it, causing a memory leak.
Before doing anything else, why are you using new[] instead of std::string? You tagged this as C++, but all of your coding is 'C'.

initializing char array in a function and returning it causes wrong outputs in main [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
char* func()
{
const int size = 24;
char bin[size];
char *temp;
for(int i=0; i<23; i++)
bin[i] = '1';
bin[23] = '\0';
temp = bin;
return temp;
}
int main()
{
char *s;
s = func();
cout << s << endl; //prints out weird values
return 0;
}
When compiled and ran, it print random values. In the function func, I initialized a char array and tried to return it. Upon returning it and printing it in main, it prints out weird values. What is wrong? Any help would be appreciated.
char bin[size];
allocate memory on the stack, you cannot refer to that location after the function returns: "char *s" is assigned a value that refer to an invalid memory location.
You must not use pointers to freed space, like the stack of a function which has finished executing.
This Undefined Behavior means anything goes, even the proverbial demons flying out of your nose.
Your choices:
Use a caller-allocated buffer.
Use a static buffer (beware reentrancy problems and multithreading woes).
Use dynamic allocation (new, new[], malloc() and friends).
return a struct (standard container or otherwise) containing the data. Might use dynamic allocation. (Last point courtesy of Matt McNabb).

Memory Management : scope and local pointer variable

Memory Management : scope and local pointer variable
Q. In terms of Memory Management, What is the error in the following code?
char* secret_message()
{
char message_buffer[100];
char* text = "Hey man!";
int n = 0;
while (text[n] != '\0')
n++;
for (int i = 0; i <= n ; i++)
message_buffer[i] = text[i];
return message_buffer;
}
Answer.
I think message_buffer is local variable
that is automatically reclaimed after function ends.
This function returns a reference to an invalid memory location
, since message_buffer disappears right after return statement.
Is it correct?
Please let me know.
Thanks,
Answer. I think message_buffer is local variable that is automatically reclaimed after function ends. This function returns a reference to an invalid memory location , since message_buffer disappears right after return statement.
Yes, it is correct. message_buffer is allocated on stack, its memory will be deallocated when the function exits. the pointer will points to release memory.
BTW:
char* text = "Hey man!";
should be
const char* text = "Hey man!";
in modern C++.
message_buffer is automatic variable whose scope is within the function only.
this variable either should be declared in main function or declared as static variable within the function.
You are correct. This produces undefined behaviour.