简体   繁体   中英

Access violation when calling strtok(); C++

I'm having trouble with this bit of code:

char KernelFS::doesExist(char* fname){
    char part;
    char name[8];
    char ext[3];

    char* token;

    token = strtok(fname, "\\");
    strncpy(&part, token, 1);

    token = strtok(fname, "\\");
    strncpy(name, token, 8);

    token = strtok(fname, "\\");
    strncpy(ext, token, 3);

    return 0;
}

It compiles and breaks when I run it at the first call of strtok(...) - Access violation writing location ... No idea why :(

I call this function with:

KernelFS::doesExist("X:\\test.exe");

the point is to separate the fname char array into 3 arrays; one for the name of the partition, one for the file name, one for the file extension;

thanks for the help ! :)

In your example:

KernelFS::doesExist("X:\test.exe");

"X:\\test.exe" is in fact of a const char* type, you cannot modify it. That raw string literal is allocated within a protected memory area, hence the error you have encountered.

char * strtok ( char * str, const char * delimiters );

str - Notice that this string is modified by being broken into smaller strings (tokens). Alternativelly, a null pointer may be specified, in which case the function continues scanning where a previous successful call to the function ended.

If you really want to use the <cstring> library (not advised though), you should rather allocate your string on a stack instead of acquiring it from the program symbols' area.

char path[] = { "X:\\test.exe" };
KernelFS::doesExist(path);

However, it is advised that you switch to the <string> library.

I suggest the following modification:

char KernelFS::doesExist(char* fname)
{
    // Our variables.
    char part[2];
    char name[9];
    char ext[4];        
    char* token;

    // Initialize variables.
    memset(part, '\0', 2);
    memset(name, '\0', 9);
    memset(ext, '\0', 4);

    // If we receive an invalid string:
    if (fname == NULL)
        return -1; // Return error.

    // Process.
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(part, token, 1);
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(name, token, 8);
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(ext, token, 3);

    // If we retrieved the 3 variables:
    if (strlen(part) > 0 && strlen(name) > 0 && strlen(ext) > 0)
    {
        // Do something with part, name and ext here.
    }

    // Return success.
    return 0;
}

As Piotr S. says, pay attention to call this function with a valid char * (not a const char * or anything else).

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