The user specifies the number of lines in the output in the arguments (as the size of the page in pagination), by pressing the key he gets the next lines. How it works now:
Let's say the user chose to receive 1 row at a time:
first string
first string
second string
first string
second string
third string
struct result {
char part[32768];
int is_end_of_file;
};
struct result readLines(int count) {
int lines_readed = 0;
struct result r;
if (count == 0) {
count = -1;
}
while (count != lines_readed) {
while (1) {
char sym[1];
sym[0] = (char) fgetc(file);
if (feof(file)) {
r.is_end_of_file = 1;
return r;
}
strcat(r.part, sym);
if (*"\n" == sym[0]) {
break;
}
}
lines_readed++;
}
return r;
}
int main(int argc, char *argv[]) {
file = fopen(argv[1], "r");
while (1) {
struct result res = readLines(atoi(argv[2]));
printf("%s", res.part);
if (res.is_end_of_file) {
printf("\nEnd of file!\n");
break;
}
getc(stdin);
}
closeFile();
return 0;
}
I know that when I define a struct in the readLines function, it is already filled with previous data. Forgive me if this is a dumb question, I'm a complete newbie to C.
I'm not sure what is the question here, however I'll do my best to address what I understand. I assume the problem lies somewhere around the "previous data" you mentioned in the title and in the comments to the question.
Let's first set an example program:
#include <stdio.h>
struct result {
char part[10];
};
int main (int argc, char *argv[]) {
struct result r;
printf(r.part);
return 0;
}
The variable r has a block scope, so it has automatic storage duration. Since it has automatic storage duration, and no initializer is provided, it is initialized to an indeterminate value (as mentioned by UnholySheep and n. 1.8e9-where's-my-share m. in the comments to the question). I don't yet get all the C intricacies, but based on this, I guess you cannot rely on what the value of r will be.
Now, in the comments to the question you try to understand how is it possible that you can access some data that was not written by the current invokation of your program. I cannot tell you exactly how is that possible, but I suspect it is rather platform-specific than C-specific. Maybe the following will help you:
What is Indeterminate value?
What happens to memory after free()?
Why memory isn't zero out from malloc?
Going further, in the line
printf(r.part);
first we try to access a member part of r, and then we call printf with the value of this member. Accessing a variable of an indeterminate value results in undefined behavior, according to this. So, in general, you cannot rely also on anything that happens after invoking r.part (it doesn't mean there is no way of knowing what will happen).
There is also another problem with this code. printf's first parameter is interpreted as having the type const char *, according to man 3 printf, but there is provided a variable that has the type struct result. Indeed, there is produced the following warning when the code is compiled with gcc with the option -Wformat-security:
warning: format not a string literal and no format arguments [-Wformat-security]
Unfortunately, I don't know C well enough to tell you what precisely is happening when you do such type mismatch in a function call. But as we know that there already happened undefined behavior in the code, this seems less important.
As a side note, a correct invokation of printf could be in this case:
printf("%p", (void *)r.part);
r.part is a pointer, therefore I use the %p conversion specifier, and cast the value to (void *).
Related
When i'm using char* pilih(char teks[]) in the int main() function, it's working. But when I used this function in the new function, it said read access violation. Please help me
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#define MAXARR 1000
char *hilangkan(char[]);
char *pilih(char[]);
char *loadFile(FILE *sumber);
int main(){
FILE *sumber;
sumber=fopen("kumpulan.txt","r");
char *teks=loadFile(sumber);
char *pilihan=pilih(teks);
printf("%s",pilihan);
printf("%s",hilangkan(pilihan));
}
char *hilangkan(char teks[]){
char *penghilangan;
strcpy(penghilangan,teks);
int y=strlen(penghilangan);
srand(time(NULL));
int c=48;
for(int i=0;i<y;i++){
int hilang=rand()%y+1;
penghilangan[hilang]='_';
}
return penghilangan;
}
char *loadFile(FILE *sumber){
char *teks;
if (sumber == NULL) {
printf("ERROR!!!");
system("pause");
return 0;
}
char h;
int count=0;
while (h = fgetc(sumber) != EOF) {
teks[count] = h;
count++;
}
fclose(sumber);
return teks;
}
char *pilih(char teks[]){
char *hasil;
srand(time(NULL));
int w = rand() % 47 + 1;
char cek[3];
itoa(w, cek, 10);
char *c=strstr(teks, cek);
int lokasi = c - teks + 1;
int pan = strlen(cek);
int i;
if (pan == 2)i = -1;
else i = 0;
while (teks[lokasi]!='\n') {
hasil[i] = teks[lokasi];
i++;
lokasi++;
}
hasil[i] = NULL;
return hasil;
}
On while(teks[lokasi]!='\n') it says read violation access. teks was 0x1110113
Links are highly discouraged and expectation from you is that, you should post the whole program in your question.
From the part of code that you have posted and the error information shared, it seems that the argument passed to pilih() function is not valid which in turn makes teks pointer pointing to some invalid memory. Actual cause of problem can only be given after looking at minimal, complete and verifiable program depicting the problematic behavior.
One confirm problem in your pilih() function is that you are returning a local variable hasil from it. The scope and life of local variable hasil is limited to pilih() function and it is no more valid once pilih() function exits.
Also, this statement
hasil[i] = NULL;
is not correct. Variable hasil is array of char and hasil[i] is a character at index i. You are assigning NULL to it which is not valid. I think you wanted to do this:
hasil[i] = '\0';
EDIT:
The full code has been posted in the question. Hence editing my answer and pointing out the problems in the OP's code.
There are several issues in your code. If you are using gcc compiler, try compiling your code with "-Wall -Wextra" options and check the warnings messages given by the compiler.
In the function loadFile(), look at this statement:
while (h = fgetc(sumber) != EOF) {
First of all, the return type of fgetc() function is int and not char [the fgetc() return type is int to accommodate for the special value EOF]. In the operator precedence table, the operator != comes before =, so you will not get the read character assigned to h but the result of fgetc(sumber) != EOF will be assigned to h. This should be
while ((h = fgetc(sumber)) != EOF) { // check the parenthesis added
^ ^
In this statement:
teks[count] = h;
You are accessing a pointer which is not initialized. Any variable which is not initialized has indeterminate value and same is true for pointers. They can point to any random indeterminate address. There is no default behavior. Only behavior is indeterminate and using indeterminate values results in Undefined behavior.
You should allocate memory to teks before using it, like this:
teks = malloc(100 * sizeof (char)); //this will allocate memory for 100 characters.
if (teks == NULL)
exit(EXIT_FAILURE);
Looks like you want to store the whole file content in teks. Make sure to allocate enough memory to teks and if you are not sure about the size of memory required then realloc is your friend.
Also, after while loop, you should add the terminating null character at the end of the content stored in teks, like this:
teks[count] = '\0';
The same error of accessing uninitialized pointer exists in hilangkan() and pilih() function. Check the variable penghilangan and hasil respectively.
strstr() can return NULL pointer. You should add check for it:
char *c=strstr(teks, cek);
if (c == NULL)
return NULL; // Or whatever the way you want to handle this case
// but you should not use c
You should check the parameter value before using it in every function. If it is pointer, check whether it is NULL or not. If it is not NULL then only use it.
Also, make sure to free the dynamically allocated memory once you are done with it.
I don't what exactly you are trying to do but somewhere I feel that there is lot of scope of improvements in your code.
Hope this help.
I fairly new to C Programming, but fprintf() & printf() is behaving strangely and I'm so confused on why--I need some help understanding and diagnosing this issue.
fprintf() Deleting Element of Array
First off, I'm passing in a populated malloc allocated four element char** array into a simple function that will write to a file, everything in the array appears normal and all four elements contain the correct data. The function call in main() looks like this. My array in question is header.
Note: I had to cast this normal (char** array) as a constant in this function parameter, due to the function header parameter. Our professor gave us the header file and we cannot change anything in them.
pgmWrite((const char**) header, (const int**) matrix,
rowPixels, colPixels, outFile);
Next, stopping debugger just before it executes the fprintf() & printf() functions, screenshot showing the array is still populated with my 4 elements.
pgmWrite() - Showing array is still fine
Observe the 4th element of the array after execution of fprintf().
After fprintf() executes, element 3 memory is wiped out.
When run, printf() executes the printing of the array exactly what is shown in the debugger, ending at the 3rd element. Often printing nothing in that spot or in rare cases garbage characters. The behavior of printf() is exactly the same as how fprintf() is working as well.
I'm at a loss here guys, please help me understand what I'm doing wrong. I can only provide these two screenshots, based on me being a new member. I'll try to provide as much information as possible. Thank you. Here is a simplified version of my program. Keep in mind, the professor gave us the function declarations and told us we cannot change them. So, I have to work with what I have here. Also, since this is fileIO, you need to find a *.pgm file to test this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define rowsInHeader 4
#define maxSizeHeadRow 200
int ** pgmRead( char **header, int *numRows, int *numCols, FILE *in ){
// INITIALIZING
char *headArr[rowsInHeader][maxSizeHeadRow];
char buffer[100];
int r = 0;
fpos_t pos;
// CREATE: Header
while (r < 4){
// IF: Row in pgm file header lists the dimensions of matrix
if (r == 2){
// CURSOR: Saving pointer location in file (see notes in header for method reference)
fgetpos(in, &pos);
// ASSIGN: Dereference column and row pointers from file
fscanf(in, "%d %d", numCols, numRows);
// CURSOR: Moving back to saved pointer location (see notes in header for method reference)
fsetpos(in, &pos);
}
// ASSIGN: Copying header row into array
fgets(buffer, maxSizeHeadRow, in);
strcpy((char*)headArr[r], buffer);
// POINTER: Reference pointer to headArr[]
header[r] = (char*)headArr[r];
// TRAVERSE: To next row in file
r++;
}
// NOTE: Placeholder for return type
return 0;
}
int pgmWrite( const char **header, const int **pixels, int numRows, int numCols, FILE *out ){
// INITIALIZING
int i = 0;
// WRITE: Header
for (i = 0; i < rowsInHeader; i++){
fprintf(out, "%s", header[i]);
printf("%s", header[i]);
}
return 0;
}
int main(int argc, char *argv[]){
char **header = (char**)malloc(rowsInHeader * sizeof(char));
FILE *inFile = fopen("smallFile.pgm", "r");
FILE *outFile = fopen("TestPicture.ascii.pgm", "w");;
int rowPixels = 0;
int colPixels = 0;
int **matrix = NULL;
// READ & WRITE
matrix = pgmRead(header, &rowPixels, &colPixels, inFile);
pgmWrite((const char**)header, (const int**)matrix, rowPixels, colPixels, outFile);
// FINALIZING
fclose(inFile);
free(header);
return 0;
}
You are not allocating your array correctly. This line:
char **header = (char**)malloc(rowsInHeader * sizeof(char));
makes header point to an uninitialized region of memory , size 4 bytes.
Then inside your PGM function you write:
header[r] = (char*)headArr[r];
The code header[r] means to access the r'th pointer stored in the space pointed to by headArr. But since that space is only 4 bytes big, you're actually writing off into the wild blue yonder.
Also, (char *)headArr[r] is a mistake. If you did not use the cast, your compiler would have warned you about this mistake. You should avoid using casts in your code, especially using them to make warnings go away. You're saying to the compiler "Ssh, I know what I'm doing" when in fact you don't know what you are doing.
The entire approach with headArr is flawed from the start: even if you had actually written the right code to implement what you were trying, you'd be returning pointers into space which is deallocated when the function returns.
Basically the whole pgmRead function is a complete mess and it'd be easier to start from scratch. But this time, think carefully about when and where you are allocating memory, and what the types are of your expressions, and don't use casts. Let the pgmRead function do all the allocation.
(Unfortunately, based on your description it looks like you will have to use your casts to call the pgmWrite function since that has a mistake in its signature. const int ** should be const int * const *, and similarly for const char **. I'd recommend to actually change pgmWrite's signature accordingly, get your program working, and then once everything is good, then go back to the broken version that you are forced to use.)
Reading C FAQ - arrays and pointers might be useful too.
I would like to do something like that :
#include <stdio.h>
char * myfunction(char * in);
void myfunction2(char * in, const char ** content);
int main(){
char * name="aName";
char * result = myfunction(name);
return 0;
}
char * myfunction(char * in) {
const char *test = NULL;
myfunction2(in, &test);
return test; // I would like to return the value of test
}
void myfunction2(char * in, const char ** content) {
char input[1024];
//do some stuff to fill input
*content = input;
}
But I'm not able to do it, some weird char are printed instead sometimes...
Thank you for your reply, I understand it well now, but I'm stuck on another side of my problem. I didn't write precisely my use case, so I edited it to be complete.
The most glaring things wrong in this code are:
Implicit declaration of myfunction as int myfunction();
Incorrect const-ness of your pointers.
No return value provided for main()
Implicit declaration of myfunction as int myfunction();
This is easy enough to solve, and your compiler should be barking loudly at you when this happens. As a legacy feature of C, when a function call is encountered where no formal declaration, either by prototype or definition, is known, the function is assumed to return int and accept a variable number of parameters. Therefore in main() your call is assumed to be to a function that looks like this:
int myfunction();
Later when the real myfunction is encountered, at a minimum your compiler should scream at you with warning about how the declaration doesn't match the expected type (because by this time it thinks it is int myfunction()). Even then, however, the call should still go through, but it is terrible practice to rely on this. Properly prototype your functions before use.
Incorrect data types for all your pointers.
The string literal in your function is not bound to local array space. It is a read-only data buffer sitting in a read-only segment somewhere in your program's data blocks. The correct declaration is this:
const char *test = "mytest";
but that has the ripple effect of requiring changes to the rest of this code, which you'll see in a moment.
No return value provided for main()
Be definitive in your conclusion of main(). Apparently C99 allows you to skip this and implementation is supposed to return 0 for you. Don't give them that joy; seize it yourself.
Addressing all of the above...
#include <stdio.h>
void myfunction(const char** in);
int main()
{
const char *result = NULL;
myfunction(&result);
printf("in main() %p : %s\n", result, result);
return 0;
}
void myfunction(const char** in)
{
const char* test = "mytest";
printf("in myfunction() %p : %s\n", test, test);
*in = test;
}
Output (varies by implementation)
in main() 0x8048580 : mytest
in myfunction() 0x8048580 : mytest
See it live.
It looks good to me. May I suggest giving it a prototype or moving your myfunc() definition before main(). Also assigning a value to result when it is declared. That will give you a better idea of what is going on if the function is not doing what you expect.
For some reason, the other answers just pointed out technical detail that's wrong, but failed to notice what is really wrong: You are returning the address of an array on the stack. But when the function returns, accessing that array becomes undefined behavior. Other code may freely overwrite the memory, leaving the worst possible garbage in it, or, conversely, writing to the memory behind the returned pointer may trash any vitally important variable of some other, entirely unconnected parts of the code.
If you want to return a pointer, you must either return a pointer to a static object, or you must return a pointer to something on the heap. Here is the static case:
char* foo() {
static char staticArray[1024];
return staticArray;
}
Using static here guarantees that the memory reserved for staticArray[] will remain reserved for it throughout the execution of your program. There are, however, three downsides of this:
the array size is fixed at compile time
this is generally not multithreading safe since all threads will use the same globally allocated memory
you generally cannot expect the data behind the returned pointer to remain intact across a function call. Consider this code:
void bar() {
char* temp = foo();
temp[0] = 7;
}
void baz() {
char* temp = foo();
temp[0] = 3;
bar();
//now temp[0] is 7 !
}
This might be desirable in some rare cases, however, in most it's not.
So, if you want to be able to freely use the memory behind the returned pointer, you have to malloc() memory for it (and free() it afterwards, of course). Like this:
char* foo(int size) {
return malloc(size);
}
void baz() {
char* sevenBytes = foo(7);
//Do something with seven bytes
free(sevenBytes);
}
void bar() {
char* threeBytes = foo(3);
threeBytes[0] = 3;
baz();
assert(threeBytes[0] == 3); //baz() worked on it's own memory
free(threeBytes);
}
In the case of string handling, there is a number of handy functions available in the POSIX-2008 standard that do the memory allocation for you, among them strdup() and asprintf(). Here are some usage examples:
int main() {
char* hello = strdup("Hello");
char* greeting;
if(0 > asprintf(&greeting, "%s World!\nMemory for hello was allocated at %llx", hello, (long long)hello)) {
//error handling
}
printf(greeting);
free(hello);
free(greeting);
}
This will print something like:
Hello World!
Memory for hello was allocated at c726de80
Thanks! Works perfectly now. Java has made me stupid :(
I am having some difficulty comparing strings in C. I get correct output when I don't use my isMorse function, but when I use it the output becomes inaccurate and displays random characters. As far as I can tell, the variable "morse" is actually changed when strcmp is called on it. I am thinking that it has to do with "morse" not being a constant, but I am unsure of how to remedy it.
Thanks!!
char *EnglishToMorse(char english)
{
static char *morse;
int i;
for (i = 0; i < LOOKUP_SIZE; i++)
{
if (lookup[i].character == english)
{
morse = lookup[i].morse;
return morse;
}
}
morse = &english; // Problem was here!!!
return morse;
}
I have a little guess. The function EnglishToMorse() might be returning a pointer to memory from the stack. If so, running another function after EnglishToMorse() will alter that memory. This would be due to a mistake in EnglishToMorse() -- declaring a local array of char and returning a pointer to it.
Without seeing the code for EnglishToMorse(), this is just a stab in the dark. You could provide us more code to look at, and win.
You have a static variable in EnglishToMorse, but it's the wrong one. There's no need for morse to be static -- you simply return it. But you do need english to be static -- rather than on the stack -- since you return its address. Also, it needs to be a NUL-terminated string. Do something like
char *EnglishToMorse(char english)
{
static char save_english[2]; /* initialized to 0's */
int i;
for (i = 0; i < LOOKUP_SIZE; i++)
if (lookup[i].character == english)
return lookup[i].morse;
save_english[0] = english;
return save_english;
}
Note, however, that the caller of EnglishToMorse must use the result or save it before EnglishToMorse is called again, since the second call may overwrite static_english.
The reason your morse variable appears to change is because it points to an area on the stack. The reason it points to an area on the stack is because you assigned it the address of your parameter english, which got pushed onto the stack when you called your function then popped off the stack once the function completed.
Now your morse variable will point to whatever memory takes that same location on the stack, which will constantly change throughout the lifetime of your program.
In my opinion, the best way to fix this problem would be to return a NULL pointer from EnglishToMorse if the character is not A-Z... then check for the NULL pointer in your isMorse function. After all, it's good practice to check for NULL pointers in code.
char* EnglishToMorse(char english)
{
int i;
english = toupper(english);
for (i = 0; i < LOOKUP_SIZE; i++)
{
if (lookup[i].character == english)
return lookup[i].morse;
}
return NULL;
}
int isMorse(char* morse)
{
int i;
/* Check for NULL, so strcmp doesn't fail. */
if (morse == NULL) return 0;
for (i = 0; i < LOOKUP_SIZE; i++)
{
if(strcmp(morse, lookup[i].morse) == 0)
return 1;
}
return 0;
}
It looks like the problem is likely in this function:
char *EnglishToMorse(char english) {
static char *morse;
// ...
morse = &english;
return morse;
}
You are returning the address of a parameter (english) that's passed into the function. This parameter ceases to exist after the function returns (and before the caller gets a chance to actually see the value). It appears as though you've attempted to fix this by declaring the morse variable static, but this only makes the morse variable itself static, not whatever it points to.
Also, strings in C must be terminated with a NUL character. By returning a pointer to a single character (as in english), there is no guarantee that the next byte in memory is or is not a NUL character. So the caller, who is expecting to see a NUL-terminated string, may get more than they bargained for.
char *EnglishToMorse(char english)
and
morse = &english;
are the problem.
You should never return a pointer to a local variable or a function parameter.
I have argument with my friend. He says that I can return a pointer to local data from a function. This is not what I have learned but I can't find a counterargument for him to prove my knowledge.
Here is illustrated case:
char *name() {
char n[10] = "bodacydo!";
return n;
}
And it's used as:
int main() {
char *n = name();
printf("%s\n", n);
}
He says this is perfectly OK because after a program calls name, it returns a pointer to n, and right after that it just prints it. Nothing else happens in the program meanwhile, because it's single threaded and execution is serial.
I can't find a counter-argument. I would never write code like that, but he's stubborn and says this is completely ok. If I was his boss, I would fire him for being a stubborn idiot, but I can't find a counter argument.
Another example:
int *number() {
int n = 5;
return &n;
}
int main() {
int *a = number();
int b = 9;
int c = *a * b;
printf("%d\n", c);
}
I will send him this link after I get some good answers, so he at least learns something.
Your friend is wrong.
name is returning a pointer to the call stack. Once you invoke printf, there's no telling how that stack will be overwritten before the data at the pointer is accessed. It may work on his compiler and machine, but it won't work on all of them.
Your friend claims that after name returns, "nothing happens except printing it". printf is itself another function call, with who knows how much complexity inside it. A great deal is happening before the data is printed.
Also, code is never finished, it will be amended and added to. Code the "does nothing" now will do something once it's changed, and your closely-reasoned trick will fall apart.
Returning a pointer to local data is a recipe for disaster.
you will get a problem, when you call another function between name() and printf(), which itself uses the stack
char *fun(char *what) {
char res[10];
strncpy(res, what, 9);
return res;
}
main() {
char *r1 = fun("bla");
char *r2 = fun("blubber");
printf("'%s' is bla and '%s' is blubber", r1, r2);
}
As soon as the scope of the function ends i.e after the closing brace } of function, memory allocated(on stack) for all the local variables will be left. So, returning pointer to some memory which is no longer valid invokes undefined behavior.
Also you can say that local variable lifetime is ended when the function finished execution.
Also more details you can read HERE.
My counter-arguments would be:
it's never OK to write code with undefined behavior,
how long before somebody else uses that function in different context,
the language provides facilities to do the same thing legally (and possibly more efficiently)
It's undefined behavior and the value could easily be destroyed before it is actually printed. printf(), which is just a normal function, could use some local variables or call other functions before the string is actually printed. Since these actions use the stack they could easily corrupt the value.
If the code happens to print the correct value depends on the implementation of printf() and how function calls work on the compiler/platform you are using (which parameters/addresses/variables are put where on the stack,...). Even if the code happens to "work" on your machine with certain compiler settings it's far from sure that it will work anywhere else or under slightly different border conditions.
You are correct - n lives on the stack and so could go away as soon as the function returns.
Your friend's code might work only because the memory location that n is pointing to has not been corrupted (yet!).
As the others have already pointed out it is not illegal to do this, but a bad idea because the returned data resides on the non-used part of the stack and may get overridden at any time by other function calls.
Here is a counter-example that crashes on my system if compiled with optimizations turned on:
char * name ()
{
char n[] = "Hello World";
return n;
}
void test (char * arg)
{
// msg and arg will reside roughly at the same memory location.
// so changing msg will change arg as well:
char msg[100];
// this will override whatever arg points to.
strcpy (msg, "Logging: ");
// here we access the overridden data. A bad idea!
strcat (msg, arg);
strcat (msg, "\n");
printf (msg);
}
int main ()
{
char * n = name();
test (n);
return 0;
}
gcc : main.c: In function ‘name’:
main.c:4: warning: function returns address of local variable
Wherever it could been done like that (but it's not sexy code :p) :
char *name()
{
static char n[10] = "bodacydo!";
return n;
}
int main()
{
char *n = name();
printf("%s\n", n);
}
Warning it's not thread safe.
You're right, your friend is wrong. Here's a simple counterexample:
char *n = name();
printf("(%d): %s\n", 1, n);
Returning pointer to local variable is aways wrong, even if it appears to work in some rare situation.
A local (automatic) variable can be allocated either from stack or from registers.
If it is allocated from stack, it will be overwritten as soon as next function call (such as printf) is executed or if an interrupt occurs.
If the variable is allocated from a register, it is not even possible to have a pointer pointing to it.
Even if the application is "single threaded", the interrupts may use the stack. In order to be relatively safe, you should disable the interrupts. But it is not possible to disable the NMI (Non Maskable Interrupt), so you can never be safe.
While it is true that you cannot return pointers to local stack variables declared inside a function, you can however allocate memory inside a function using malloc and then return a pointer to that block. Maybe this is what your friend meant?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* getstr(){
char* ret=malloc(sizeof(char)*15);
strcpy(ret,"Hello World");
return ret;
}
int main(){
char* answer=getstr();
printf("%s\n", answer);
free(answer);
return 0;
}
The way I see it you have three main options because this one is dangerous and utilizes undefined behavior:
replace: char n[10] = "bodacydo!"
with: static char n[10] = "bodacydo!"
This will give undesirable results if you use the same function more than once in row while trying to maintain the values contained therein.
replace:
char n[10] = "bodacydo!"
with:
char *n = new char[10];
*n = "bodacydo!"
With will fix the aforementioned problem, but you will then need to delete the heap memory or start incurring memory leaks.
Or finally:
replace: char n[10] = "bodacydo!";
with: shared_ptr<char> n(new char[10]) = "bodacydo!";
Which relieves you from having to delete the heap memory, but you will then have change the return type and the char *n in main to a shared_prt as well in order to hand off the management of the pointer. If you don't hand it off, the scope of the shared_ptr will end and the value stored in the pointer gets set to NULL.
If we take the code segment u gave....
char *name() {
char n[10] = "bodacydo!";
return n;
}
int main() {
char *n = name();
printf("%s\n", n);
}
Its okay to use that local var in printf() in main 'coz here we are using a string literal which again isn't something local to name().
But now lets look at a slightly different code
class SomeClass {
int *i;
public:
SomeClass() {
i = new int();
*i = 23;
}
~SomeClass() {
delete i;
i = NULL;
}
void print() {
printf("%d", *i);
}
};
SomeClass *name() {
SomeClass s;
return &s;
}
int main() {
SomeClass *n = name();
n->print();
}
In this case when the name() function returns SomeClass destructor would be called and the member var i would have be deallocated and set to NULL.
So when we call print() in main even though since the mem pointed by n isn't overwritten (i am assuming that) the print call will crash when it tried to de-reference a NULL pointer.
So in a way ur code segment will most likely not fail but will most likely fail if the objects deconstructor is doing some resource deinitialization and we are using it afterwards.
Hope it helps