473,395 Members | 1,999 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

return of pointer

Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?

Thanks a lot!
--
Sergey Koveshnikov.
Nov 13 '05 #1
19 11151
In article <bo**********@dcs.eurocom.od.ua>, Sergey Koveshnikov wrote:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
Maybe not, but as long as you are consistent and document the
interface it works well.
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?


You can't force someone to remember to call free().

Creating a foo_alloc() and a foo_free() function might help
though (untested):

#include <stdlib.h>
#include <stdio.h>

int foo_alloc(char **p)
{
/* sanity checks of *p here */

*p = malloc(10);
if (*p == NULL) return 1;
strcpy(*p, "something");
return 0;
}

int foo_free(char **p)
{
/* sanity checks of *p here */

free(*p);
*p = NULL;

return 0;
}

void bar()
{
char *p;

foo_alloc(&p);
printf("foo: %s\n", p);

foo_free(&p);
}


--
Andreas Kähäri
Nov 13 '05 #2
i.e. No way to do automatic cleanup dynamic allocated memory, if it's
unnecessary anywhere, except context of 'bar()', isn't it?
--
Sergey Koveshnikov.
Nov 13 '05 #3
In article <bo**********@dcs.eurocom.od.ua>, Sergey Koveshnikov wrote:
i.e. No way to do automatic cleanup dynamic allocated memory, if it's
unnecessary anywhere, except context of 'bar()', isn't it?


There is no built-in garbage collector in C, no.

--
Andreas Kähäri
Nov 13 '05 #4
But, what can I do if some foreign code expect from my function that it will
return char*, and it doesn't call free()? Do you know any 'save string'
library for ANSI C that provide self-destroyed strings?
May be it's possible to solve this problem with macros or 'static' type?

PS. Sorry if my questions are stupid, I'm new in the C.
--
Sergey Koveshnikov.
Nov 13 '05 #5
Sergey Koveshnikov <ac*****@eurocom.od.ua> wrote:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?


Maybe it's a good idea to adopt the bevaviour of, for example, the
standard library string functions, and let the caller take the full
responsibility for memory allocation/deallocation. E.g.:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BIG_ENOUGH 50

char *foo( char *p )
{
if ( p != NULL )
strcpy( p, "something" );
return( p );
}

int main( void )
{
char *p = malloc( BIG_ENOUGH );
if ( foo( p ) != NULL )
printf( "%s\n", p );
free( p );
return 0;
}

Note: you may want foo() to take an additional argument specifying the
buffer size, in order to avoid buffer overflows.

OTOH, if you, for example, want to imitate the non-standard strdup
function, you of course have to allocate the memory inside the function,
document the behaviour and hopefully the user of the function will get
it right.

HTH
Regards
--
Irrwahn
(ir*******@freenet.de)
Nov 13 '05 #6
In article <bo**********@dcs.eurocom.od.ua>, Sergey Koveshnikov wrote:
But, what can I do if some foreign code expect from my function that it will
return char*, and it doesn't call free()? Do you know any 'save string'
library for ANSI C that provide self-destroyed strings?
May be it's possible to solve this problem with macros or 'static' type?

PS. Sorry if my questions are stupid, I'm new in the C.


You, as a library implementor, are not required to make sure
that the users of the library writes correct code.

Document the correct usage (whether to explicitly free() storage
or to call a special cleanup function), and that's the end of
your troubles.

It is possible to return a pointer to a static array, but you
will have to make sure that you point this out to the library
user as well, so that he/she doesn't wander off and tries to
free() that pointer, or so that he/she doesn't store its value
somewhere and gets confused when the data it points to suddenly
changes after the next call to your function.

My favourite solution is to provide two functions; one for
allocation and one for deallocation. This is a bit too involved
if it's just a question of a simple string and not a struct or
some opaque data type.

--
Andreas Kähäri
Nov 13 '05 #7
In <bo**********@dcs.eurocom.od.ua> Sergey Koveshnikov <ac*****@eurocom.od.ua> writes:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?


This is a perfectly valid approach. No matter where the memory is
dynamically allocated, someone may forget to release it. This is an
intrinsic issue with dynamically allocated memory.

The alternative is to pass to foo the address of the buffer. If the
buffer was not dynamically allocated, no need to release it:

#define STRING "something"

void foo(char *p)
{
strcpy(p, STRING);
}

void bar()
{
char p[sizeof STRING];
foo(p);
printf("%s\n", p);
}

Of course, this doesn't work if only the called function can evaluate
the size of the buffer.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #8
Sergey Koveshnikov wrote:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?

Thanks a lot!


Sergey...

You may be able to write a wrapper for malloc() that keeps a list
of all allocations it makes, then write a function to call free()
for each of the allocations in that list. Refine as necessary.

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall very far from the tree.

Nov 13 '05 #9
On 2003-11-04, Sergey Koveshnikov <ac*****@eurocom.od.ua> wrote:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?

Thanks a lot!


You can design a callback interface to someone that wants the
memory:

void foo(void (*cb)(char *))
{
char *p = malloc(10);
if (p)
strcpy(p, "something");
cb(p);
free(p);
}

void mycallback(char *p)
{
printf("%s", p);
}

void bar(char *p)
{
foo(mycallback);
}

-- James
Nov 13 '05 #10
In <bo**********@dcs.eurocom.od.ua> Sergey Koveshnikov <ac*****@eurocom.od.ua> writes:
But, what can I do if some foreign code expect from my function that it will
return char*, and it doesn't call free()?
You only need to worry about the correctness of the code you write
yourself. No matter what you do or don't, someone may use your code
incorrectly. It's his problem, not yours. That is, assuming that you
have properly documented the correct usage of your code.
Do you know any 'save string'
library for ANSI C that provide self-destroyed strings?
There is no way to write such a library in C.
May be it's possible to solve this problem with macros or 'static' type?


The only way to solve this problem is by using automatic allocation in
the function that is calling your function and passing the address (and,
possibly, the size of the allocated block) to your function. The string
will self-destroy when the function that allocated it returns.

The other "solution", return the address of a statically allocated buffer
inside your function, which is reused at each invocation of your
function, has its own big caveat: if the caller forgets to make a local
copy of the buffer before calling the function again, he ends up with a
hard to find bug. Typical example: imagine that your function returns
a random string each time it's called, in a statically allocated buffer.
What happens to the following printf call:

char *randstr(void)
{
static char alnum[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static char str[10];
int i;

for (i = 0; i < sizeof str - 1; i++)
str[i] = alnum[rand() % strlen(alnum)];
return str;
}
....
printf("%s %s\n", randstr(), randstr());

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #11

On Tue, 4 Nov 2003, James Hu wrote:

On 2003-11-04, Sergey Koveshnikov <ac*****@eurocom.od.ua> wrote:

If my function return a pointer on a memory area, where do I free it? [snip] But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget
to call free()?
You can design a callback interface to someone that wants the
memory:


[snip code example]
void bar(char *p)
ITYM void bar(void) here.
{
foo(mycallback);
}

Wow -- I'd never seen that approach before! It's... interesting,
but I can't really see myself ever using it. :-)
[Just in case the OP didn't get it the first time around: here,
'bar' is the "main" function of the program, and 'foo' is the
function that encapsulates everything to do with a single dynamic
object. 'mycallback'/'cb' is a pointer to a function that says,
"After creating the object, do this and this and this; once that's
done, it's safe to free the object again."]
So to use my favorite example, we could take an image format
converter that looked like this [NOT REAL CODE]:

struct Im
{
unsigned char *data;
int w, h;
};

int main(int argc, char **argv)
{
struct Im *image;
ReadPGM(argv[1], &image);
WritePPM(argv[2], image);
free(image->data);
free(image);
return 0;
}

void ReadPGM(const char *fname, struct Im *im)
{
/* something like... */
im = malloc(sizeof *im);
im->w = im->h = 42;
im->data = malloc(im->w * im->h);
}
and transform it into this:

static const char *OutFileName = NULL;

int main(int argc, char **argv)
{
OutFileName = argv[2];
ProcessPGM(argv[1], write_it_out);
return 0;
}

void write_it_out(struct Im *im)
{
WritePPM(OutFileName, im);
}

void ProcessPGM(const char *fname, void (*cb)(struct Im *))
{
struct Im *image;
ReadPGM(argv[1], &image);
cb(image);
free(image->data);
free(image);
}
Uglier in this case, but possibly this could save a few
keystrokes and possible memory leaks down the road. :-)

HTH,
-Arthur
Nov 13 '05 #12
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote in message news:<Pi***********************************@unix50 .andrew.cmu.edu>...
On Tue, 4 Nov 2003, James Hu wrote:

void bar(char *p)
ITYM void bar(void) here.


Yes, thanks.
Wow -- I'd never seen that approach before! It's... interesting,
but I can't really see myself ever using it. :-)


The original poster just asked if there was a solution that didn't
require the user of the interface to call free to reap the memory.
I just wanted to demonstrate that there was one that did not require
a garbage collection facility.

-- James
Nov 13 '05 #13
Morris Dovey wrote:

Sergey Koveshnikov wrote:
Hello, [ lots of snips ] But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?

Thanks a lot!


Sergey...

You may be able to write a wrapper for malloc() that keeps a list
of all allocations it makes, then write a function to call free()
for each of the allocations in that list. Refine as necessary.

Morris,

I have done just that. I have a 'library' called GE for Garbage
Eliminator. With a little preprocessor magic it traps the *alloc() calls
and free(). GE manages a list of structures which hold the pointers to
allocated memory and the size of the allocation. A library function
'size_t size(void *p)' will look up p in the list and return its
allocated size (or 0 if p is not found). free(void *p) is trapped and
and looks up p and frees it and its entry in the list if found,
otherwise does nothing. A library function freeall() will free all
allocations including the list itself.

--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #14
Joe Wright wrote:
I have done just that. I have a 'library' called GE for
Garbage Eliminator. With a little preprocessor magic it traps
the *alloc() calls and free(). GE manages a list of structures
which hold the pointers to allocated memory and the size of
the allocation. A library function 'size_t size(void *p)' will
look up p in the list and return its allocated size (or 0 if p
is not found). free(void *p) is trapped and and looks up p and
frees it and its entry in the list if found, otherwise does
nothing. A library function freeall() will free all
allocations including the list itself.


Joe...

Damn I'm good! ( Too bad you beat me to it. 8-)

I particularly like your size() function. 'Xcuse me while I go
plagerize^H^H^H^H^H^H^H^H^H(ahem) make some notes...
--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall very far from the tree.

Nov 13 '05 #15

"Dan Pop" <Da*****@cern.ch> wrote in message
news:bo**********@sunnews.cern.ch...
In <bo**********@dcs.eurocom.od.ua> Sergey Koveshnikov <ac*****@eurocom.od.ua> writes:
But, what can I do if some foreign code expect from my function that it willreturn char*, and it doesn't call free()?
You only need to worry about the correctness of the code you write
yourself. No matter what you do or don't, someone may use your code
incorrectly. It's his problem, not yours. That is, assuming that you
have properly documented the correct usage of your code.


(snip)
The other "solution", return the address of a statically allocated buffer
inside your function, which is reused at each invocation of your
function, has its own big caveat: if the caller forgets to make a local
copy of the buffer before calling the function again, he ends up with a
hard to find bug. Typical example: imagine that your function returns
a random string each time it's called, in a statically allocated buffer.


(snip)

Or consider the ctime() C library function and a program to print the
creation, modification, and last access time for a file.

printf("%s %s %s\n",ctime(created),ctime(modified),ctime(accesse d));

(yes, it actually happened to me. It didn't take long to figure it out, but
it did happen.)

-- glen
Nov 13 '05 #16
Morris Dovey wrote:
Joe Wright wrote:
I have done just that. I have a 'library' called GE for
Garbage Eliminator. With a little preprocessor magic it traps
the *alloc() calls and free(). GE manages a list of structures
which hold the pointers to allocated memory and the size of
the allocation. A library function 'size_t size(void *p)' will
look up p in the list and return its allocated size (or 0 if p
is not found). free(void *p) is trapped and and looks up p and
frees it and its entry in the list if found, otherwise does
nothing. A library function freeall() will free all
allocations including the list itself.


Damn I'm good! ( Too bad you beat me to it. 8-)

I particularly like your size() function. 'Xcuse me while I go
plagerize^H^H^H^H^H^H^H^H^H(ahem) make some notes...


ALL those features are available in nmalloc.zip, available at:

<http://cbfalconer.home.att.net/download/>

which was written for the DJGPP system, and should work on any
system whose fundamental allocation scheme depends on sbrk and
deals with 8 bit bytes. The extension function memalign() is not
ready. An equivalent to the size function you mention is
trivially implemented, and could be added to the malldbg module.

The code is very close to standard C, with the principal deviation
being the use of GCC varargs macros for debugging purposes.
Because of the form of call these don't simply define away. Those
macros also use non-standard write calls, the purpose being to
allow them to function during initialization, at least under
DJGPP.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #17
"Glen Herrmannsfeldt" <ga*@ugcs.caltech.edu> writes:
"Dan Pop" <Da*****@cern.ch> wrote in message
news:bo**********@sunnews.cern.ch...
In <bo**********@dcs.eurocom.od.ua> Sergey Koveshnikov

<ac*****@eurocom.od.ua> writes:
But, what can I do if some foreign code expect from my function that it willreturn char*, and it doesn't call free()?


You only need to worry about the correctness of the code you write
yourself. No matter what you do or don't, someone may use your code
incorrectly. It's his problem, not yours. That is, assuming that you
have properly documented the correct usage of your code.


(snip)
The other "solution", return the address of a statically allocated buffer
inside your function, which is reused at each invocation of your
function, has its own big caveat: if the caller forgets to make a local
copy of the buffer before calling the function again, he ends up with a
hard to find bug. Typical example: imagine that your function returns
a random string each time it's called, in a statically allocated buffer.


(snip)

Or consider the ctime() C library function and a program to print the
creation, modification, and last access time for a file.

printf("%s %s %s\n",ctime(created),ctime(modified),ctime(accesse d));

(yes, it actually happened to me. It didn't take long to figure it out, but
it did happen.)


Another solution I've used in the past is to declare a static array of
objects of the result type, and rotate among the elements for each
call. For example:

#include <stdio.h>

char *twice(char *s)
{
#define RESULT_COUNT 6
static char result[RESULT_COUNT][100];
static int index = -1;

index ++;
if (index >= RESULT_COUNT) index = 0;

strcpy(result[index], s);
strcat(result[index], s);
return result[index];
}

int main(void)
{
printf("twice(\"foo\") = \"%s\", twice(\"bar\") = \"%s\"\n",
twice("foo"), twice("bar"));
return 0;
}

This lets me have up to RESULT_COUNT active calls to the function
without collisions, while not requiring the caller to allocate or
deallocate the result. It's not particularly pretty, and it can run
into problems if the caller saves a pointer to the result, but I found
it useful.

Probably the worst feature of this approach is that any problems are
likely to be rare, showing up only in unusual circumstances. It
handles the easy cases and doesn't do much for the really hard ones.
It also introduces the temptation of kludging around any problems by
increasing RESULT_COUNT.

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #18
CBFalconer wrote:
ALL those features are available in nmalloc.zip, available at:

<http://cbfalconer.home.att.net/download/>

which was written for the DJGPP system, and should work on any
system whose fundamental allocation scheme depends on sbrk and
deals with 8 bit bytes. The extension function memalign() is not
ready. An equivalent to the size function you mention is
trivially implemented, and could be added to the malldbg module.

The code is very close to standard C, with the principal deviation
being the use of GCC varargs macros for debugging purposes.
Because of the form of call these don't simply define away. Those
macros also use non-standard write calls, the purpose being to
allow them to function during initialization, at least under
DJGPP.


Sorry. I knew you had a pile of memory management functions on
the web - I just forgot.

Sergey, browse Chuck's site - he writes pretty good stuff...

--
Morris Dovey
West Des Moines, Iowa USA
C links at http://www.iedu.com/c
Read my lips: The apple doesn't fall very far from the tree.

Nov 13 '05 #19
Da*****@cern.ch (Dan Pop) wrote in message news:<bo**********@sunnews.cern.ch>...
In <bo**********@dcs.eurocom.od.ua> Sergey Koveshnikov <ac*****@eurocom.od.ua> writes:
Hello,
If my function return a pointer on a memory area, where do I free it?
e.x.:
char *foo()
{
char *p;
p = malloc(10);
strcpy(p, "something");
return(p);
}
void bar()
{
char *p = foo();
printf("%s", p);
free(p);
}
But force anybody to calling free() after use foo() not elegant solution,
for my mind... How can I avoid posible memory leaks if somebody forget to
call free()?


This is a perfectly valid approach. No matter where the memory is
dynamically allocated, someone may forget to release it. This is an
intrinsic issue with dynamically allocated memory.

The alternative is to pass to foo the address of the buffer. If the
buffer was not dynamically allocated, no need to release it:

#define STRING "something"

void foo(char *p)
{
strcpy(p, STRING);
}

void bar()
{
char p[sizeof STRING];
foo(p);
printf("%s\n", p);
}

Of course, this doesn't work if only the called function can evaluate
the size of the buffer.


an alternative is to have the called function be able to
return the size of the buffer needed.

#define STRING "something"

size_t foo (char *p, size_t size) {
size_t needed_size = strlen (STRING) +1;
if (p==NULL || size < needed_size) {
return needed_size;
}
strcpy (p, STRING);
return 0;
}

void bar ()
char *the_string = NULL;
size_t size_of_the_string = 0;

/* get the amount of memory needed */
size_of_the_string = foo (NULL, 0);

the_string = malloc (size_of_the_string);
if (!the_string) {
/* report error!!! */
} else {
foo (the_string, size_of_the_string);
}
}
goose,
criticise away :-)
Nov 13 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: Gama Franco | last post by:
Hi, I'm designing an interface for a shared library, and I would like to know if there is a standard about how to return an object to the user. I will use exceptions to report errors, so there...
5
by: Neal Coombes | last post by:
Posted to comp.lang.c++.moderated with little response. Hoping for better from the unmoderated groups: -------- Original Message -------- Subject: Return appropriately by value, (smart)...
14
by: William Ahern | last post by:
is this legal: FILE *func(void) { extern int errno; return (errno = EINVAL, NULL); } my compiler (gcc 2.9.x on openbsd) is complaining that i'm returning a pointer from int w/o a cast....
10
by: LaEisem | last post by:
On-the-job, I have "inherited" a lot of old C language software. A question or two about when "casting" of null pointer constants is needed has occurred during behind-the-scenes cleanup of some...
4
by: Isaac | last post by:
Hi mates I want to know a simple program of return array from function ? Do I need to use pointer to return the address of the first element in an array. Isaac
23
by: Nascimento | last post by:
Hello, How to I do to return a string as a result of a function. I wrote the following function: char prt_tralha(int num) { int i; char tralha;
4
by: msolem | last post by:
I have some code where there are a set of functions that return pointers to each other. I'm having a bit of a hard time figuring out the correct type to use to do that. The code below works but...
32
by: zl2k | last post by:
hi, c++ user Suppose I constructed a large array and put it in the std::vector in a function and now I want to return it back to where the function is called. I can do like this: ...
18
by: Pedro Pinto | last post by:
Hi there once more........ Instead of showing all the code my problem is simple. I've tried to create this function: char temp(char *string){ alterString(string); return string;
9
by: Francois Grieu | last post by:
When running the following code under MinGW, I get realloc(p,0) returned NULL Is that a non-conformance? TIA, Francois Grieu #include <stdio.h> #include <stdlib.h>
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.