Reputation: 418
// reading
if((shmid = shmget(key, 0, 0)) < 0) {
perror("shmget");
exit(50);
}
// attach
if((data = shmat(shmid, (void *)0, 0)) == (char *) -1) {
perror("shmat");
exit(100);
}
// get memory size
struct shmid_ds shm_info;
size_t shm_size;
int shm_rc;
if((shm_rc = shmctl(shmid, IPC_STAT, &shm_info)) < 0)
exit(101);
shm_size = shm_info.shm_segsz;
Sometimes data is not null terminated and calling strlen(data) causes segfaults...
So I was trying to make sure that it is null terminated by making
data[shm_size] = '\0';
But now sometimes it fails on that line of code.
What I'm doing wrong?
EDIT: Thanks for your support! I think after your explanation about the strlen() + 1 == shm_size I have changed the rest of my code not posted here and seems to be fine. I'm waiting for new segfaults and hopefully I will not get any ;)
Upvotes: 4
Views: 353
Reputation: 32530
By doing
`data[shm_size] = '\0';`
you're actually accessing a memory region outside the bounds of the shared memory ... the data[index_value]
syntax on a pointer pointing to a raw memory block is the same as saying
*(data + index_value*sizeof(unsigned char))
Thus data[0]
will dereference and return the value at the first memory address in the shared memory segment, and data[shm_size]
will do the same at and address past the end of the shared-memory segment.
Upvotes: 2
Reputation: 91099
data[shm_size]
is one beyond the end. You should, instead, do data[shm_size-1]
, and only if shm_size != 0
.
But nevertheless, calling strlen()
makes only sense if you really have put a string inside it. Otherwise, it might return any value < shm_size
if there happens to be a \0
character.
Upvotes: 1
Reputation: 5370
first: the memory has not to be null terminated. it is undefined at the beginning. you might want to consider using
memset(data,0,shm_size);
and second:
data[shm_size] = '\0';
is wrong by one index. arrays begin at zero so you should use
data[shm_size-1] = '\0';
Upvotes: 3
Reputation: 41242
The assignment of the null termination character:
data[shm_size] = '\0';
is writing past the end of the allocated memory, which is undefined behavior. If it the buffer has character data of length shm_size
, then it will be necessary to copy it to another buffer in order to null terminate it.
Upvotes: 2