I have an array of strings as follows:

char *sCmdInt[8];

I need to use elements from the array to pass to another dll. The function takes two LPSTRs as parameters. What I need to do is copy two elements from the array into ints/longs, and then create two LPSTRs from those. I cannot pass the array elements directly, as this causes an access violation:

DIAG_ReadMem32(sCmdInt[1], sCmdInt[2]);

Any suggestions as to how to make totally independent copies? The values held in the array may be hex (can these be converted to int/long?)

Thanks

Dani AI

Generated

Short diagnosis and practical fixes (builds on and )

If the DLL writes into the second parameter you must supply writable memory whose lifetime you control. Tokens returned by strtok are pointers into the original buffer (or into read-only storage if they came from a literal), so passing them directly can cause an access violation when the callee tries to modify that memory.

Make an independent, writable copy of each token before calling the DLL. On POSIX you can use strdup; on Windows use _strdup or allocate with malloc and copy. Example helper and usage:

char *make_copy(const char *src) {
    if (!src) return NULL;
    size_t n = strlen(src) + 1;
    char *dst = malloc(n);
    if (dst) memcpy(dst, src, n);
    return dst;
}

/* usage */
char *p1 = make_copy(sCmdInt[1]);
char *p2 = make_copy(sCmdInt[2]);
if (p1 && p2) {
    DIAG_ReadMem32(p1, p2);
}
free(p1); free(p2);

If the strings actually contain numeric addresses (hex text) and the function expects pointers, convert the text to an integer and cast to a pointer — but only if the API really expects an address value, and only after verifying that the address is valid in the current process. Example (use with extreme caution):

#include <stdint.h>
unsigned long long v = strtoull(sCmdInt[1], NULL, 0); /* base 0 accepts 0x */
char *addr = (char *)(uintptr_t)v;
DIAG_ReadMem32(addr, /* other arg */);

Checklist and cautions

  • Confirm DIAG_ReadMem32 signature and whether it expects writable buffers or addresses.
  • Ensure buffers are large enough for what the DLL will write.
  • Keep allocated copies alive for the call and free after.
  • Use a debugger to inspect pointer values passed to the DLL if crashes continue.

Recommended Answers

All 5 Replies

There is no reason why this should not work, unless the function DIAG_ReadMem32 is attempting to change the contents of either of those pointers.

char *sCmdInt[8] = {0};
sCmdInt[0] = "123";
sCmdInt[1] = "234";
DIAG_ReadMem32(sCmdInt[0], sCmdInt[1]);

If the values in the array are hex numbers, such as "0x100", then you can use strtol() to convert them to integers

int x;
char str[] = "0x123";
char *ptr = 0;
x = strtol(str,&ptr, 16);

The function does attempt to change the contents of the second parameter. How is this usually resolved?

String literals can not be changed because most compilers put them into read-only memory. How to change that? Notice that you have to make each buffer large enough to hold whatever it is that DIAG_ReadMem32() wants to copy into it. If you don't know exactly how big to make it, take a guess then double it.

char sCmdInt[8][255] = {0};
strcpy(sCmdInt[0],"123");
strcpy(sCmdInt[1],"234");
DIAG_ReadMem32(sCmdInt[0], sCmdInt[1]);

Is this the only resolution? Isn't is possible to make an independent copy of the value pointed to by sCmdInt[x]? sCmdInt is built up using the strtok function, which only returns pointers.

Of course there are other solutions. And the one you suggested will work too. Just create another buffer and copy the contents of sCmdInt into it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.