简体   繁体   中英

Char* Constant From Previous Line Being Added Into Char* Array

When I was working on a small header file, I came across something strange. Basically, I declare a char* variable "file". On the next line, I create a char*[] array with a few set values. However, every single time I test this the "test.txt" contents from "file" gets appended to the end of "data[]"... and I do not have any clue why. Attached is the most simplistic form I could get the code.

In my file main.cpp:

#include <iostream>
using namespace std;

int main() {
    char* file = "test.txt";
    const char* data[] = {"test6", "test7", "test8"};

    for (int i = 0; i < 4; i++)
    {
        cout << data[i];
    }

    return 0;
}

I'm compiling simply using

g++ main.cpp

And yes, I did use a set value in the loop ("4"). It doesn't matter, but I used a set value because "sizeof(data)" was crashing it.

(Also ignore the "file" variable name... this code doesn't have anything to actually do with file writing.)

When compiling, I get

main.cpp: In function 'int main()':
main.cpp:5:18: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     char* file = "test.txt";
                  ^

...although this shouldn't affect much.

Changing the type to "const char*" or even "string" does not work.

Does anyone know how to resolve this issue? or is it just me?

The number of elements in data is 3, not 4 so you're accessing out of bounds data in your loop. The result of that is undefined behavior. Since undefined behavior is - well, undefined - anything can happen.

You could do it like this instead :

for (int i = 0; i < sizeof data / sizeof *data; i++)
{
    cout << data[i];
}

The reason you have to do the division is that sizeof data equals the number of elements in data (which is 3) times the size of each element (which is probably 4 or 8 depending on your compiler). So you have to divide by the size of each element. (Elements being pointers, not characters.)

As for the warning, you could declare file like this:

const char *file = "test.txt";

Try this:

#include <iostream>

using namespace std;

int main() {
    string file = "test.txt";
    const char* data[] = {"test6", "test7", "test8"};

    for (int i = 0; i < 3; i++)
    {
        cout << data[i];
    }
    return 0;
}

The issue was that you were casting the string as a char pointer. (Ps your for loop was out of bounds)

A string literal (Like "test.txt" above) is a constant pointer, but you are assigning it to a non-const pointer ( char *file ). Instead, try declaring file as an array type:

char file[] = "test.txt";

When you create simple variable like you have done here, they get stored in memory next to each other usually. In case of array this is almost certain. For example see this code:

#include<iostream>


int main()
{
   int i=0;
   int a[] = {1,2,3};
   int c = 10;
   for(i=0;i<5;i++)
     std::cout << a[i] << std::endl;
}

So, here there is a very high possibility that memory will be allocated in continuous blocks like this :
| a[0] - a[1] - a[2] - i - c | or
| i - a[0] - a[1] - a[2] - c |

Depending on the case your output will be : 1,2,3,3,10 or 0,1,2,3,10 Now in your case similar thing happens(though the memory type used in this example and your case is different) as you are going beyond the bounds of an array, data[3] accesses the data in the very next block. Hence, the output cannot be predicted accurately its just random.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM