Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

copy an array in c

Name: Anonymous 2007-03-12 22:30 ID:016HOAcL

I have a function, it accepts a char**, what is the quickest and most efficient way of making a local copy of the array in the function scope?

That is, i have , for example:

void funk(char **x){

char **b;

/*How do i make a separate copy of x to b?*/
}

Take pity on me internets, I'm a noob :) Thanks.

Name: Anonymous 2007-03-12 22:39 ID:N1Caoytj

You want something taht for example takes argv and copies it somewhere right?
Read about pointers to arrays (so you don't use another variable like while(x[i][0])strcpy(b[i], x[i++]);) and use strcpy.
that's a multiarray btw, not just a regular array.

Name: Anonymous 2007-03-12 23:47 ID:eCN+flAQ

memcpy?

Name: Anonymous 2007-03-13 0:13 ID:2/Slvb9r

Well first you'd have to know the size of the two-dimensional array. That's impossible to know with a two-dimensional array unless explicity specified. Your c-style strings will be null-delimited but there's no way to know how many of those c-style strings there are.

Unless you want to copy that string on the free store, just declare your two-dimensional array on the stack, like so:
char b[x][y]; // assuming you know x and y

Then it's simple. Create a loop that iterates 'x' number of times and use strcpy() to copy the c-style, null-delimited strings (assuming these -are- null-delimited strings).

Name: Anonymous 2007-03-13 2:14 ID:rBeysgNR

>>4
what if you don't know y?

Name: Anonymous 2007-03-13 2:23 ID:fRPueBDP

memcpy

Name: Anonymous 2007-03-13 3:16 ID:2/Slvb9r

>>6
This is an obvious troll (or someone really stupid) so I'm not taking the bait.

>>5
So what you're saying is you know -how many- null delimited c-style strings there are, but not the length of the strings themselves? Well, that's simple enough to solve.

Just loop and copy all the characters, including the null delimeter, into a second array (knowing how large this second array should be beforehand is another issue entirely, you could use a linked-list type structure if you need an expanding array. The vector template in C++ comes in handy here, I'm not sure what C has since I've never bothered learning it.). Initialize a counter variable and for each null character you encounter and pass to the second array increment it by one. Once your counter reaches 'y,' copy the final null character and quit the loop.

Name: Anonymous 2007-03-13 4:16 ID:Heaven

One word, the iterative memcpy of c strings. Thread over.

Name: Anonymous 2007-03-13 4:28 ID:rBeysgNR

>>7
>>5 was also an obvious troll.

Name: Anonymous 2007-03-13 5:05 ID:Dbo5b/lS

>>7
This is an obvious troll (or someone really stupid) so I'm not taking the bait.
Meta-troll. >>6 was right, you're the one who's trolling.

Name: Anonymous 2007-03-13 7:10 ID:hq0mUcKP

>>5
If you know x AND y, you can just malloc(x * y * sizeof(char)), then memcpy the whole block in.

If you only know x, i.e. it's a "ragged array" like argv, then iteration and strcpy/strncpy is the way to go. Keep track of the buffer length, and extend the buffer each iteration to that length using realloc (don't forget to init your pointer to NULL first). The required space for a C null-terminated string is strlen + 1, so that's what you add. If you use strncpy, make sure you set the null terminator yourself.

Can be done in a single loop, but if you prefer your memory allocated once, you can go x times through the array, using  the strlen logic above, and just malloc that big block. After that, you could probably use memcpy like in the "x AND y" situation.

If you don't know x, you're stuffed.

Name: Anonymous 2007-03-13 7:53 ID:Heaven

Maybe he just wants to make a copy of the pointer. In which case "char **b = x;" is JUST FINE.

Name: Anonymous 2007-03-13 8:06 ID:Heaven

>>11
that only works if the pointers in x[] are consecutive...

Name: Anonymous 2007-03-13 8:54 ID:PjPu/Qkk

Hmm thanks guys for the suggestions. Right now, I'm using a loop to copy each value to the array one element at a time after mallocing the second array. I'm just curious if there was a shortcut to do doing this. I should have been more clear, here is my revised problem.

void funk(char **x,int size){
/*x is SQUARE array, size is given*/
char **b;
/*Now I wish to make a local copy, so that I can manipulate b within the function and not affect x at all.*/

}

Name: Anonymous 2007-03-13 9:40 ID:L+IY2zIp

for(int i=0;i<size;++i){
 b[i]=malloc(strlen[x[i]]);
 strcpy(b[i],x[i]);
}

Name: Anonymous 2007-03-13 9:42 ID:Heaven

b[i]=malloc(strlen[x[i]]);
that should be:
b[i]=malloc(strlen(x[i]));

OTL

Name: Anonymous 2007-03-13 10:32 ID:Dbo5b/lS

>>1
shell> python
>>> import copy
>>> funk = copy.deepcopy


Here you go.

Name: Anonymous 2007-03-13 17:37 ID:Heaven

>>17
Too bad python is slow as fuck.

Name: Anonymous 2007-03-14 1:04 ID:MUtl/82E

>>16
Which should be
b[i] = malloc((strlen(x[i]) + 1) * sizeof char);

Name: Anonymous 2007-03-14 2:04 ID:8NJO2imA

need to pass in len of x, then:

char **b = malloc(sizeof(*x) * n)
for (i = 0; i < n; i++) {
  if (!x[i]) b[i] = 0
  else b[i] = strdup(x[i])
}


 

Name: Anonymous 2007-03-14 2:06 ID:8NJO2imA

I've been programming in Python too long, need some semicolons there.

Name: Anonymous 2007-03-14 4:08 ID:Heaven

>>20
>>21
Same person

Name: Anonymous 2007-03-14 9:15 ID:SyvzrMNb

>>22
Captain Obvious to the rescue!

Name: Anonymous 2007-03-14 11:49 ID:YijmFcOk

Too bad null-terminated strings are slow as fuck.

Name: Anonymous 2007-03-14 16:05 ID:MaZOFci/

Too bad null-terminated strings are DANGEROUSLY CHEESY!

Name: Anonymous 2007-03-14 19:00 ID:Cv044S7v

Too bad null-terminated strings are WHAT'S FOR BREAKFAST!

Name: Anonymous 2007-03-14 19:05 ID:MRqk0VHa

Too bad null-terminated strings are SLOW AS FUCK!

Name: Anonymous 2007-03-14 19:22 ID:1OGioET1

Too bad null-terminated strings are braindead. How could the guys who invented C and Unix use null-terminated strings? Unforgivable.

Name: Anonymous 2007-03-14 19:48 ID:Cv044S7v

>>28
Normally I'd take you up on this statement on any other message board but the unfortunate fact is that a good percentage of the posts here are blatant trolls.

Not that there's anything wrong with that, it's just there isn't much of a reason to be factual because demonstrating your knowledge is usually ego-driven. Since we're on an anonymous message board we have nothing to associate with our ego so it's much easier to let things like that by and also say, "No, cock sucker, you're wrong."

Name: Anonymous 2007-03-14 20:02 ID:8eqq087m

>>29
No, cock sucker, you're wrong.

Name: Anonymous 2007-03-14 20:39 ID:1OGioET1

>>29
No, cock sucker, you're wrong. Null-terminated strings are braindamaged.

- Non-binary safe.
- O(n) length.
- Twice as expensive concatenation.
- Hinders possible word transfer optimizations for O(n) operations.
- More easily exploitable (e.g. Windows registry entries with null characters in their names, possible in Win32 but hidden from regedit.exe from being written in C).

Name: Anonymous 2007-03-14 23:12 ID:1w3ZGCoJ

>>31
- Non-binary safe.
why do strings need to be binary safe? only an idiot would store anything other than ascii or utf-8 text in a string.

- O(n) length.
- Twice as expensive concatenation.
- Hinders possible word transfer optimizations for O(n) operations.
if you're working with strings so long you even notice those you're doing something wrong.

- More easily exploitable (e.g. Windows registry entries with null characters in their names, possible in Win32 but hidden from regedit.exe from being written in C).
i can write shitty code in python/ruby/haskell/whatever language you think is superior, too.
just because microsoft can't convince anyone with more than e^(i/(2ln(i^i)+pi)) brain cells to work for them...

Name: Anonymous 2007-03-15 2:28 ID:2HoFjLyQ

>>31
Ok, cock sucker, that was me you were referring to. I love you smug bastards who think you know better than tried, tested and true technologies.

First of all you seem to be comparing a language that was designed as a "high level assembly" of sorts with a modern language with bounds checking and other such niceties. Stop.

Secondly, as >>32 said:
>only an idiot would store anything other than ascii or utf-8 text in a string.

Also if we're talking in terms of the O(n) length of a string a null-delimited string is much more memory efficient than the second-best alternative, that being storing an integer specifying how many characters long a string is (what is that, one byte vs. four bytes on most platforms?). The other advantage of a null-delimited string over having an integer specifying how long the string is is that the latter has a maximum length while the former has no such limit.

If you disagree with my last statement I challenge you to design a string structure more memory efficient than c-style strings. Because, y'know, memory/time efficiency is kind of what C is all about and I'm sure somebody smarter than you or I would have figured out something better, if it existed, long ago.

Name: Anonymous 2007-03-15 5:37 ID:3/0l364P

>>32
Because that's when they become useful. Oh, and efficient strings need to be UTF-16 or UTF-32.

if you're working with strings so long you even notice those you're doing something wrong.
That's retarded.

i can write shitty code in python/ruby/haskell/whatever language you think is superior, too.
But when a language provides you with null-terminated strings, you have to go out of your way and do it yourself in order to NOT write shitty code.

>>33
First of all you seem to be comparing a language that was designed as a "high level assembly" of sorts with a modern language with bounds checking and other such niceties. Stop.
If you say C isn't capable of decent strings, then you're bashing C, not me.

The other advantage of a null-delimited string over having an integer specifying how long the string is is that the latter has a maximum length while the former has no such limit.
Be real. How often would you want to use null bytes in strings or to have O(1) length, faster concatenation, better optimizations, etc., versus having strings larger than fucking 4 GB?

Because, y'know, memory/time efficiency is kind of what C is all about
If you're so CFLAGS JUST KICKED IN, YO!-oriented, you'd want O(1) length and faster string operations. Plus -O3 -mword-strings -malign-double would provide you with awesome word-by-word string optimizations! OMG recompile your kernel!

>>32-33
Seriously, why's that? Why are you being such a fag? Are you a C fanboy? This is kind of lame. What advantages would null-terminated strings have? Length and storage space marked strings are much, much better any day for any purpose. The only advantages of null-terminated strings, to save space on tiny strings, and to get past 4 GB length is nothing compared to its huge disadvantages.

Name: Anonymous 2007-03-15 8:19 ID:Heaven

>>31,33-34
[pedantic]
O(n) is the set of all algorithms that have a maximum upper bound that grows linearly in proportion to n.

string == data structure
data structure != algorithm
[/pedantic]

Name: Anonymous 2007-03-15 8:24 ID:2HoFjLyQ

>>34
"Better optimizations"? Teach me your crazy moon language.

Name: Anonymous 2007-03-15 9:28 ID:XfLHn/jy

>>35
When did >>31 or >>34 say that any string is O(n) or O(1)? I've always talked about length.

>>36
You have to copy null-terminated strings byte per byte. Yet if you knew the length beforehand, you could shift it first to calculate the number of 64 or 32 bit words it has, then copy it word by word, which is much faster, then copy the remaining bytes (and the length to get how many).

Name: Anonymous 2007-03-15 9:34 ID:Heaven

Oh god, not this shit again.

Name: Anonymous 2007-03-15 17:56 ID:acmPTe2g

I think the other guy wrapped it up quite nicely, but I'd like to add the following:

why do strings need to be binary safe? only an idiot would store anything other than ascii or utf-8 text in a string.
Yes, because C-style strings won't allow it. This is what is called thinking in a box.

Also, the other guy didn't mention that Pascal-style strings make slicing nice and easy. This counters the "saves memory" argument.

The other advantage of a null-delimited string over having an integer specifying how long the string is is that the latter has a maximum length while the former has no such limit.
I'd like to know how many architectures allow a process to access a memory space larger than what a pointer can handle? The closest I can think of is x86 PAE, yet only an OS can access the full 36-bit memory space (apps are limited to the regular 4GB). So why have such a default then?

Yet another problem with null-terminated strings is redundant code. Consider how many standard library functions could be unified if strings were 8-bit safe.

Name: Anonymous 2007-03-15 17:56 ID:NDP2IfqJ

Here is the answer:
void funk(char **x) {
    char **b = x;
}

Name: Anonymous 2007-03-15 18:11 ID:acmPTe2g

Answer to what?

Name: Anonymous 2007-03-16 7:15 ID:cZZ6uzeL

It's kind of pointless arguing about null-terminated strings in C. Want to use the standard libraries? You don't really have a choice _but_ to use them. Don't want null-terminated strings? Roll your own string API, and be prepared to not be able to pass your custom strings to the standard library system functions which expect them.

Name: Anonymous 2007-03-16 7:47 ID:gF+Kn3aW

>>41
See post >>42 for the question.

Name: Anonymous 2008-04-23 10:00

Copying arrays? Forget it, it's NP-Complete.

Name: Anonymous 2009-03-06 13:44

Pointer to the array is too short   to read SICP   and achieved Satori   PROGRAMMING IS ALL   YOU NEED OTHERWISE   YOU ARE A   few other alternatives   but none are   all that mature   yet From what   I gather so   what should I   call you Kris   reading from my   socialist state I   said a buggy!

Name: Anonymous 2010-12-17 1:29

Are you GAY?
Are you a NIGGER?
Are you a GAY NIGGER?

If you answered "Yes" to all of the above questions, then GNAA (GAY NIGGER ASSOCIATION OF AMERICA) might be exactly what you've been looking for!

Name: Sgt.Kabu聸၍kiman焾ᾔ 2012-05-28 23:12

Bringing /prog/ back to its people
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy

Name: Anonymous 2012-05-28 23:57


// assuming x is a null terminated array of null terminated strings
// untested
void funk(char **x) {
    // calculate length of x
    size_t len;
    for (len = 0; x[len]; ++len);
    // allocate copy
    char **copy = malloc((len + 1) * sizeof(*x));
    // copy over strings
    for (size_t i = 0; i < len; ++i) {
        copy[i] = malloc(strlen(x[i]));
        strcpy(copy[i], x[i]);
    }
    // add null terminator
    copy[len] = 0;
}

Name: Anonymous 2012-05-29 0:02

>>51

I forgot nulls on strings


// assuming x is a null terminated array of null terminated strings
// untested
void funk(char **x) {
    // calculate length of x
    size_t len;
    for (len = 0; x[len]; ++len);
    // allocate copy
    char **copy = malloc((len + 1) * sizeof(*x));
    // copy over strings
    for (size_t i = 0; i < len; ++i) {
        size_t _len = strlen(x[i]);
        copy[i] = malloc(_len + 1);
        strcpy(copy[i], x[i]);
        copy[_len] = 0;
    }
    // add null terminator
    copy[len] = 0;
}

Name: Anonymous 2012-05-29 0:03

>>52

oops copy[_len]...


// assuming x is a null terminated array of null terminated strings
// untested
void funk(char **x) {
    // calculate length of x
    size_t len;
    for (len = 0; x[len]; ++len);
    // allocate copy
    char **copy = malloc((len + 1) * sizeof(*x));
    // copy over strings
    for (size_t i = 0; i < len; ++i) {
        size_t _len = strlen(x[i]);
        copy[i] = malloc(_len + 1);
        strcpy(copy[i], x[i]);
        copy[i][_len] = 0;
    }
    // add null terminator
    copy[len] = 0;
}

Name: Anonymous 2012-05-29 0:05

>>53

oh strcpy copys over null terminated so i need to change this again.


// assuming x is a null terminated array of null terminated strings
// untested
void funk(char **x) {
    // calculate length of x
    size_t len;
    for (len = 0; x[len]; ++len);
    // allocate copy
    char **copy = malloc((len + 1) * sizeof(*x));
    // copy over strings
    for (size_t i = 0; i < len; ++i) {
        size_t _len = strlen(x[i]);
        copy[i] = malloc(_len + 1);
        strcpy(copy[i], x[i]);
    }
    // add null terminator
    copy[len] = 0;
}

Don't change these.
Name: Email:
Entire Thread Thread List