I need to implement bzero, I've read the manual, I saw a lot of posts about it on StackOverflow, but what I'm asking for is a simple example where you use bzero, I didn't find any simple example of using bzero instead of using it in server/client in C.
Ok so this is my memset:
void *my_memset(void *b, int c, size_t len)
{
char *pb;
unsigned char car;
if (b == NULL)
return (NULL);
pb = b;
car = (unsigned char)c;
while (len--)
{
*pb++ = car;
}
return (b);
}
void ft_bzero(void *s, size_t n)
{
ft_memset(s, 0, n);
}
Looks fine?
All bzero() does is memset everything to zero.
myStruct_t * foo = malloc (sizeof(myStruct_t));
bzero(foo, sizeof(myStruct_t));
// All bytes of foo are now 0
It's no different from calling
memset (foo, 0, sizeof(myStruct_t));
Under the hood, bzero() should match this implementation...
void bzero(void * s, size_t n)
{
char * c = s; // Can't work with void *s directly.
size_t i;
for (i = 0; i < n; ++i)
c[i] = '\0';
}
The simplest example:
char *test = malloc(256);
memset(test, 0, 256); // or bzero(test, 256);
This will set all elements of test to zero.
Notice that memset returns a pointer when bzero don't. So if you want to reproduce the bzero(), this would probably be more like :
void ft_bzero(void *s, size_t n)
{
unsigned char *ptr;
while (n-- > 0)
*ptr++ = 0;
}
Related
I need to write a code for my UNI, in which I have to receive 2 arrays of some data (it may be int array or char array or even float array) and compare n characters from pointers in both of the arrays, so far I am stuck with this
*note in other words - I need to write my own memcmp :
int byte_compare(const void *b1,const void *b2,size_t len)
{
char *q1 = (char *)p1;
char *q2 = (char *)p2;
int i;
for (i=0; i<=len*sizeof(*q1) ;i++)
{
if(*q1++ != *q2++)
return 1;
}
return 0;
}
int main()
{
char str1[] = "abcheya";
char str2[] = "gtyheyb";
printf((byte_compare(str1[3],str2[3],3))?"not equal\n":"equal\n");
/*the output is equal*/
int arr1[]={1,2,3,4};
int arr2[]={1,2,7,59};
printf((byte_compare(arr1[0],arr2[0],3))?"not equal\n":"equal\n");
/*the output is also equal although it is not supposed to be*/
return 0;
}
when I compare strings it works just fine, but when I try to compare int or float it wont work properly, please help me.
You should calculate the comparing byte length while passing the len parameter. So, you can use templates for this.
template<typename T>
int byte_compare(const T *b1, const T *b2, size_t len)
{
return memcmp(b1, b2, len * sizeof(T));
}
Edit note : The question is edited and the answer has no more meaning. And it uses C++, not applicable for C lessons. I'm remaining the answer for whose have no restriction to use C++.
Edit: to write own memcmp function
int byte_compare(const void *b1,const void *b2,size_t len)
{
if (len != 0) {
register const unsigned char *p1 = b1, *p2 = b2;
do {
if (*p1++ != *p2++)
return (*--p1 - *--p2);
} while (--len != 0);
}
return (0);
}
You need to pass the size of the objects, not their length:
int byte_compare(const void *b1, const void *b2, size_t size)
{
return memcmp(b1, b2, size);
}
Your instructor probably does not want you to use a library call. So write a byte by byte comparison (aka memcmp).
Get a copy of K&R C (or another book on C), and you will find examples of how to process char(acter) values in a loop.
int byte_compare(const void *b1,const void *b2,size_t len)
{
if( !b1 || !b2 ) return 0; //0 represents false
char* p1=(char*)b1; char* p2=(char*)p2;
for( ; len --> 0; ) {
if( *p1++ != *p2++ ) return 0;
}
return 1;
}
I can't figure out what seems to be the problem that I get a segmentation fault from this:
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
void alloc(unsigned char *data) {
data = (unsigned char *) malloc(20);
memset(data, 0, 20);
}
void main() {
unsigned char *data = NULL;
int i;
alloc(data);
for (i = 0; i < 20; i++) {
data[i] = i;
printf("%d ", *(data + i));
}
free(data);
}
Unsigned char is 1 byte so the loop through 20 should be correct
void alloc(unsigned char *data) {
data = (unsigned char *) malloc(20);
memset(data, 0, 20);
}
modifies a local copy of your pointer. You could pass it by reference to make your example work:
void alloc(unsigned char *&data) {
data = (unsigned char *) malloc(20);
memset(data, 0, 20);
}
It seems that your program is written in C instead of C++. In C++ you should use operator new [] instead of malloc.
The problem with the function is that function parameters are its local variables. So the function parameter char *data is a copy of its argument declared in main like
unsigned char *data = NULL;
So any changes of the parameter in function alloc do not influence on the original argument. After exiting the function the parameter (local variable) will be destroyed and the original variable in main will not be changed.
You have two approaches. Either you declare the function the following way
void alloc(unsigned char **data) {
*data = (unsigned char *) malloc( 20 );
if ( *data ) memset( *data, 0, 20 );
}
and call it like
alloc( &data );
Or you declare the function the following way
unsigned char * alloc() {
unsigned char *data = (unsigned char *) malloc( 20 );
if ( data ) memset( data, 0, 20 );
return data;
}
and call it in main like
data = alloc();
Take into account that function main shall be decalred in C like
int main( void )
^^^
and in C++ like
int main()
^^^
You could also return the pointer, rather than passing it to the function.
unsigned char *alloc() {
unsigned char *data = (unsigned char *) malloc(20);
memset(data, 0, 20);
return data;
}
And then,
...
unsigned char *data = alloc();
int i;
...
You tagged C++, but your code looks like C. If you really are trying to write C++ you shouldn't be using malloc. Either use new[] or the appropriate smart pointers.
EDIT: You're using void main(). Don't do that.
What should main() return in C and C++?
I wrote a function to compare 2 strings, return int as compare result, and pass an additional int pointer as param to retrieve the max match lengh.
// compare 2 strings
#include <stdio.h>
/**
* compare 2 string,
*
* #param sa
* string 1
* #param sb
* string 2
* #param len
* a int pointer pass from outside to store match length,
*
* return
* 0 if equlas, <0 if (a < b), >0 if (a > b),
*/
static int strCompare (char *sa, char *sb, int *len) {
for((*len)=0; *sa==*sb; sa++,sb++, (*len)++) {
// handle equals case, prevent ++ for \0,
if(!*sa)
break;
// printf("%c,%c\n", *sa, *sb);
}
return *sa - *sb;
}
int main(int argc, char *argv[]) {
if(argc < 3) {
printf("need 2 arguments.\n");
return 0;
}
int matchLen = 0;
int result = strCompare(argv[1], argv[2], &matchLen);
printf("compare:\n\t%s\n\t%s\nresult: %d\nmatch length: %d\n", argv[1], argv[2],
result, matchLen);
return 0;
}
Question:
I want the loop be more brief, e.g. avoid the if inside for, but didn't found out by myself, can anyone help to write a brief version with the same function interface.
(Please don't use libc function, I do this to improve my code style ;)
You might want to avoid the repeated reads and writes through the pointer while you are at it, and go for const-correctness:
static int strCompare (const char *sa, const char *sb, int *len) {
int tlen = 0;
while(*sa && *sa == *sb)
++tlen, ++sa, ++sb;
*len = tlen;
return *sa - *sb;
}
Or maybe better with restrict:
static int strCompare (const char *sa, const char *sb, int * restrict len) {
*len = 0;
while(*sa && *sa == *sb)
++*len, ++sa, ++sb;
return *sa - *sb;
}
BTW: The only thing making the code more efficient in the first case is avoiding the repeated writes through len.
In the second, it's using restrict and thus reducing aliasing (which will also remove all but the last write).
Also, consider whether size_t would not be a better type for the length.
Perhaps something like:
static int str_compare(const char *a, const char *b, size_t *len) {
const char *p = a;
for ( ; *p && *p == *b; ++p, ++b)
;
*len = p - a;
return *p - *b;
}
As Duplicator has mentioned use const for input strings.
Also size_t is widely used for sizes and counts, so likely better.
Alternative by tracking length:
static int str_compare(const char *a, const char *b, size_t *n) {
for (*n = 0; a[*n] && a[*n] == b[*n]; ++*n)
;
return a[*n] - b[*n];
}
Does not look too good with all the indirection on n, but still.
As a side note; you should return 1 (or something other then 0) on error (in main).
In your code if condition is needed. Because you are checking the pointer. If you accessing the pointer that is not allocate that will give you a segmentation fault. So avoid this you
have to do the if condition. Or else you can made that in the for loop.
for((*len)=0; *sa==*sb && *sa!='\0' ; sa++,sb++, (*len)++);
So avoiding the segmentation fault you need the another condition for checking.
How can I implement a substring function such as the following that returns the substring but without using malloc() in the process so I don't have to worry about freeing the associated memory elsewhere in my code using the free() function. Is this even possible?
const char *substring(const char *string, int position, int length)
{
char *pointer;
int c;
pointer = malloc(length+1);
if (pointer == NULL)
{
printf("Unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
for (c = 0 ; c < position -1 ; c++)
string++;
for (c = 0 ; c < length ; c++)
{
*(pointer+c) = *string;
string++;
}
*(pointer+c) = '\0';
return substr;
}
UPDATE: 30 DEC 2012
Having considered all the answers and comments it's clear that essentially what I'm trying to do is create a dynamically sized array (i.e. the substring) and that is not possible in C without somewhere along the way having to use some kind of malloc() function and a subsequent free() call on the substring pointer or without the aid of a garbage collector. I attempted to integrate the libgc garbage collector as kindly suggested by #elhadi but so far have not been able to get this to work in my Xcode project. So I have opted to stick with using the following code with malloc() and free().
char * subStr(const char* srcString, const int offset, const int len)
{
char * sub = (char*)malloc(len+1);
memcpy(sub, srcString + offset, len);
sub[len] = 0;
return sub;
}
int main()
{
const char * message = "hello universe";
char * sub = subStr( message, 6, 8 );
printf( "substring: [%s]", sub );
free(sub);
}
I see two options:
If you can destroy the source string (usually a bad thing):
{
string[ position + length] = 0;
return & string[ position ];
}
Note: (see Cole Johnsons note: free no longer works on the returned pointer!)
If you can't modify the source string:
Modify your methods signature so that the caller has to worry about it:
const char *substring(const char *source, char* destination, int position, int length)
And put the modified string into destination (and return it).
And do not even think about this:
const char *substring(const char *string, int position, int length)
{
char *pointer;
int c;
static char modifiedString[256];
...
return modifiedString;
}
Using a static variable inside the function for the modified results...
(This is not thread-safe (not re-entrant!) )
Use a local buffer (an auto array) and a function like this:
void substr(char *dst, const char *src, size_t loc, size_t len)
{
memcpy(dst, src + loc, len);
dst[len] = 0;
}
Call it like this:
const size_t size = 3;
char buf[size + 1]; // this is an auto array, it will be "freed" at the end of the scope
substr(buf, "abcdFOObar", 4, size);
Always ensure the buffer is at least len + 1 bytes long to avoid buffer overflow errors.
const char *substring(const char *string, char *substr, int position, int length)
{
int c;
for (c = 0 ; c < position -1 ; c++)
string++;
for (c = 0 ; c < length ; c++)
{
*(substr+c) = *string;
string++;
}
*(substr+c) = '\0';
return substr;
}
calling function...
int main(int argc, char * argv[]) {
char substr[10];
substring("hello! World", &substr[0], 2, 4);
}
The best way to do it is:
typedef struct vstr_t {
char *s;
int len;
} vstr_t;
#define vstr_set(d, l) \
({ \
vstr_t vs = {.s = d, .len = l}; \
\
vs; \
})
#define vstr_fmt_arg(vs) (vs).len, (vs).s
int main()
{
const char *message = "hello universe";
printf( "substring: [%.*s]\n", vstr_fmt_arg(vstr_set(smpl + 6, 8)));
return 0;
}
You can use a garbage collector, you allocate the memory the first time, the garbage collector will free the memory when no needed.
you should include
#include "gc.h"
in the main you should make something like
GC_INIT(); /* Optional on Linux/X86;*/
and your substr function is:
char *substr(const char* buffer, const int offset, int len)
{
char sub = (char*)GC_MALLOC(len+1);
memcpy(sub, buffer + offset, len);
sub[len] = 0;
return sub;
}
you should link with libgc.a
I fall in some problem.
I need to write some function like memcpy(void*, const void*), which its signature should be:
void arrayCopy(void *dest, int dIndex, const void *src, int sIndex, int len)
I noticed that, in many implementation of memcpy, we cast void* to char*, but I think this is not the case of me, as the arrayCopy function needed to be used on arrays of many types including structs.
So, how can I accomplish this?
EDIT:
the source code might be something like that:
#include <stdio.h>
#include <string.h>
void arrayCopy(void *, int, const void *, int, int, size_t);
int main(void)
{
int i;
int dest[10] = {1};
int src [] = {2, 3, 4, 5, 6};
arrayCopy(dest, 1, src, 0, 5, sizeof(int));
for (i=0; i<10; i++) printf("%i\n", dest[i]);
return 0;
}
void arrayCopy(void *dest, int dIndex, const void *src, int sIndex, int len, size_t size)
{
char *cdest = (char*) dest;
const char *csrc = (char*) src;
int i;
len *= size;
if (dest == src)
{
printf("Same array\n");
}else
{
cdest += (dIndex * size);
csrc += (sIndex * size);
for (i=0; i<len; i++)
*cdest++ = *csrc++;
}
}
Thanks.
"char * " is just a bunch bytes, everything in C is ultimately bytes - you can cast a pointer to any data structure to char* (you will also need to know the size in memory of the structure)
The function must have an element-size info, eg:
void *arrayCopy(void *dest, size_t di,const void *src, size_t si, size_t num, size_t esize)
{
char *cdest = (char*) dest;
const char *csrc = (char*) src;
return memcpy( &cdest[esize*di], &csrc[esize*si], esize*num );
}
...
arrayCopy(dest, 1, src, 0, 5, sizeof*src);
You cannot work with objects of type void. The Standard doesn't allow that. So you need to cast the void away, and the best type to use is unsigned char. There's a guarantee by the Standard that unsigned char can access all bits of any other type representable in your system.