-3

I use fopen() in my c++ program and I tried to open a .aff file.

I want to parse a file named car_wheel.aff and after if(ifp=fopen(path,"r")) has executed, it seems the fopen() function changes my path variable???

I add some detail to my question to the comment.

code (since variable path is constructed by my code, I put the whole piece of code here, which may seem a bit redundant.)

    char* dir = "../kitchen/";
    char filename[100];
    char* path;
    FILE *ifp;
    int detail_level;
    if(fscanf(fp,"%d %s",&detail_level,filename)!=2)
    {
        printf("Error: could not parse include.\n");
        exit(0);
    }

    path = (char*)malloc(strlen(dir)+strlen(filename));
    strcpy(path, dir);
    strcat(path, filename);    // path is "../kitchen/car_wheel.aff"
    if(detail_level<=gDetailLevel)
    {
        if(ifp=fopen(path,"r"))
        {
            viParseFile(ifp);
            fclose(ifp);
        }
        else
        {
            // jumped here and path became "../kitchen/car_wheel.aff1\002"
            if (ifp == NULL) {
                perror(path);
                exit(EXIT_FAILURE);
            }
            printf("Error: could not open include file: <%s>.\n",filename);
            exit(1);
        }
    }

I debugged the code in my ide, and it gave the filename char array is enter image description here

and there is no '1\002' behind my filename variable. What happened??

jinglei
  • 3,269
  • 11
  • 27
  • 46

1 Answers1

3

The problem is here:

path = (char*)malloc(strlen(dir)+strlen(filename));

You don't allocate space for the terminating zero character. Change it to this:

path = (char*)malloc(strlen(dir)+strlen(filename)+1);
SBS
  • 806
  • 5
  • 13
  • Thanks for your reply. This does solve my problem. But I was wondering, when `malloc`, does the allocated space automatically set all the char to `NULL`? – jinglei Aug 07 '17 at 08:40
  • @Jinglei.Y `malloc` definitely does not initialize the allocated memory. – Jabberwocky Aug 07 '17 at 08:41
  • 1
    If you read the manual page - it does not. You need `calloc` instead. Better methods are available when using C++ – Ed Heal Aug 07 '17 at 08:41
  • @MichaelWalz So do I need to set the last character to `NULL`? If the last character is a random char, why my program perform as I expect now. Is it a coincidence or not? Thanks. – jinglei Aug 07 '17 at 08:46
  • 2
    No matter wheter the allocated buffer is initialized with zeroes or not, you're lacking space at the end of your string, so it's not properly terminated. – SBS Aug 07 '17 at 08:46
  • 4
    @Jinglei.Y no need to set the terminating character to 0. The strcat() function does this for you. Read the documentation of the C runtime functions. – SBS Aug 07 '17 at 08:47
  • 3
    Your code would be fine if you had `malloc(strlen(dir)+strlen(filename) + 1`. Without the `+1` your code exhibits _undefined behaviour_ (google that term) and therefore it _may_ appear to work fine. – Jabberwocky Aug 07 '17 at 08:48
  • @user6060561 Thanks a lot. – jinglei Aug 07 '17 at 08:48
  • 3
    `strcpy` / `strcat` handle the NULL-termniator correctly. But they write out of bounds, because you allocated 1 byte less as required, which is UB. That 1 byte of memory does not belong to you, and could be used by any other object in your program - e.g. your `fopen` call. That's what you experienced – king_nak Aug 07 '17 at 08:49
  • 1
    @Jinglei.Y Please don't forget to mark my answer as the accepted answer if it solved your problem. – SBS Aug 07 '17 at 08:50
  • 2
    Why wouldn't you just use `std::string` and avoid all this nonsense? – David Schwartz Aug 07 '17 at 08:55