简体   繁体   中英

Passing unique_ptr to strtok

I am facing an issue with the legacy code. The legacy code uses a char array whose size is 1024 and is being passed to strtok c function.

char record[1024] = { '\0' };
char *token = NULL;
strcpy(record, inputString);// 'inputString' very large string.
token = strtok(record, DELIMETER);

And now because of new requirement, I have to modify the size to 20000 bytes and in many places they have declared this type ( record )of local variable.

Now we are compiling the code with C++11 compiler and since we are using C++11 compiler, I was planning to modify the char array to unique_ptr as shown...

#define MAX_RECORD 50000
auto record = std::make_unique<char[]>(MAX_RECORD * 4);
char *token = NULL;
strcpy(record.get(), inputString);
token = strtok(record.get(), DELIMETER);

My question is, can I pass the unique_ptr to strtok function as the record variable gets modified inside the strtok function?

Thanks in advance.

Passing a unique_ptr to a function represents a transfer of ownership of that memory to the function. And in a way, that's kind of what strtok does, since it will keep hold of that pointer beyond the execution of that function. But since it's a C function, it cannot effectively represent that in its interface.

What you have to do is what you're doing now: manage memory for strtok . You need to keep that unique_ptr alive for as long as your code requires strtok to be able to access it. In the previous code, it was stack memory. In your code, it's heap memory owned by a stack object. Either way, the memory ownership semantics work.

Unless the original code was broken (ie: someone called strtok with NULL outside the scope of the array). In which case your new code will be broken in the same way. Though likely, it will break more visibly.

My question is, can I pass the unique_ptr to strtok function as the record variable gets modified inside the strtok function?

To get proper answer, you need to ask correct question. Statement that strtok() modifies record variable is incorrect, it may modify memory, where record points to, but it cannot modify variable record itself. That different things and it is important here. So answer to corrected question is no, you cannot pass std::unique_ptr directly to strtok() obviously, as it is C++ object and strtok() is C function. But yes, you can pass underlying pointer managed by std::unique_ptr , and you need to maintain lifetime of std::unique_ptr object itself long enough that it would not break strtok() requirements of that memory.

About code, it is not clear why you need std::unique_ptr and strcpy() at all:

std::string record = inputString;  // make a copy, if you cannot modify inputString, or pass inputString itself
token = strtok(record.data(), DELIMETER);

in this case you just need to maintain lifetime of variable record the same way, but you do not need to deal with strcpy() and memory allocation.

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