Ask your own question, for FREE!
Mathematics 15 Online
OpenStudy (anonymous):

What is wrong with the following code: http://ideone.com/xTbwI

OpenStudy (anonymous):

Sorry I don't know C++ =(

OpenStudy (anonymous):

can you be more specific?

OpenStudy (anonymous):

@No-data It's in C @ktklown I was just wondering if the repr_array function could be done in a better way.

OpenStudy (anonymous):

so you're saying it works correctly but you're looking for style tips?

OpenStudy (anonymous):

right. I'm also wondering if it could be written to run faster/consume less space.

OpenStudy (anonymous):

well your memory allocation computation is a little weird. why are you computing n = ((N-1)*3 + 1? what does n represent?

OpenStudy (anonymous):

n is the number of bytes to allocate for each number, space, and comma character.

OpenStudy (anonymous):

that's not what the code says

OpenStudy (anonymous):

so for an array of 10 digits, that's (10-1)*3 + 1 bytes

OpenStudy (anonymous):

what does the code say?

OpenStudy (anonymous):

n would be the correct number of bytes to allocate if each number were only a single digit

OpenStudy (anonymous):

but then you multiply that entire thing by PLACES_MAX which is the maximum number of digits per number

OpenStudy (anonymous):

right... the function used to only work for single digit positive integers, but then I forgot to update stuff when I made it work for any integer

OpenStudy (anonymous):

but you're multiplying n times places_max, which means you're assuming each number, each space, and each comma can all be places_max bytes.

OpenStudy (anonymous):

right.

OpenStudy (anonymous):

so do you see how that is wrong?

OpenStudy (anonymous):

http://ideone.com/ERUTG Alright, what else is now wrong :-D

OpenStudy (anonymous):

you're also multiplying that all by sizeof(result), which is wrong; why are you multiplying by the size of a pointer?

OpenStudy (anonymous):

wait, your 'n' computation in the new code still doesn't make sense. why are you multiplying by 3?

OpenStudy (anonymous):

I should multiply by 3, since I write each number together with a trailing comma and space character. Good point about the sizeof(result)... forgot to add a star

OpenStudy (anonymous):

so doesn't that mean "add two" instead of multiply by three?

OpenStudy (anonymous):

why would multiplying places_max*3 be what you want?

OpenStudy (anonymous):

right http://ideone.com/GDmhx

OpenStudy (anonymous):

ok, that looks better. for style, first, why did you write "1 <= N" instead of what you really meant, which is "n >= 1"?

OpenStudy (anonymous):

I might forget and write n = 1

OpenStudy (anonymous):

with <= and >= you can't make that error anyway; it just makes the code harder to read, and that's 10x more likely to cause a bug. Say what you mean so that the code's meaning is immediately obvious to anyone reading it. Also, "if (n = 0)" is flagged by every modern compiler as a warning anyway.

OpenStudy (anonymous):

right

OpenStudy (anonymous):

I honestly didn't understand this code without thinking carefully about it for 15 seconds, whereas if you'd written: if (N < 1) { return NULL; } it would have been immediately obvious.

OpenStudy (anonymous):

so that brings me to my next suggestion which is to write the code above and pull the rest of the code out of the conditional.

OpenStudy (anonymous):

http://ideone.com/SSMZH

OpenStudy (anonymous):

so I should write the 'return null' part before the part where n is computed? alright

OpenStudy (anonymous):

I'd write if (N <= 0) { return NULL; } That makes it immediately obvious what your intent is. To return an error if N is 0 or less. There's no logic sense in putting the computation inside the conditional. If the input is valid, you're going to run both the n computation *and* everything else in the rest of the function. Why just put a few lines inside the conditional and the rest below outside the conditional?

OpenStudy (anonymous):

By putting those 2 lines of code inside the conditional it makes them seem somehow special, but they're not: they run along with everything else in the function below. But by setting them apart, again the code is much less readable, it seems like there might be some case where you don't compute N but still run the rest of the function.

OpenStudy (anonymous):

I'd say the same goes for your next conditional. Change it to if (result == NULL) { fprintf(stderr, "out of memory"); return NULL; } and take the common case out of the conditional.

OpenStudy (anonymous):

that way the common-case flow of your program is what's in the main line and the exceptions are all in the conditionals.

OpenStudy (anonymous):

and finally for the string generation part, nothing there is wrong, but to make it more readable I might do this: result[0] = '['; char *s = result+1; for (j = 0; j < N-1; j++) { sprintf(s, "%d, ", A[j]); s += strlen(s); } for() loops here are easier to read than while() loops because you're putting all the initialization, per-loop increment, and termination condition on the same line, rather than spreading them out over three lines.

OpenStudy (anonymous):

http://ideone.com/qs23s

OpenStudy (anonymous):

so as i said earlier take out the elses

OpenStudy (anonymous):

everything in the entire function is going to run if N<=0 fails, why put some inside an else?

OpenStudy (anonymous):

I put another incase malloc fails

OpenStudy (anonymous):

also your array optimizing code you added is not correct; it doesn't account for the initial '[' or the final number, or nulls. just keep the j loop as it was before and add at the end result = realloc(result, strlen(result*sizeof(*result)+1); However in reality that's not actually going to save you much memory.

OpenStudy (anonymous):

both the N<=0 check and the reslut==NULL check should just be simple comparisons with a return in them and no else{}.

OpenStudy (anonymous):

realloc rarely saves memory in practice because of heap fragmentation, so if you actually wanted to optimize the size of the array (at the expense of cpu time) the solution would be to test-sprintf all the numbers. By the way, little known fact, sprintf() returns the number of characters converted. So your inner loop can actually look like this: for (j = 0; j < (N-1); ++j) { s += sprintf(s, "%d, ", A[j]); }

OpenStudy (anonymous):

I forgot all about that stuff: the return value of the printf family! :-P as well as the reason why realloc() here is actually unecessary thanks

OpenStudy (anonymous):

yw

OpenStudy (anonymous):

Alright my code is like this now: http://ideone.com/cURFL

OpenStudy (anonymous):

what happened to your N <= 0 check?

OpenStudy (anonymous):

why did you change from malloc to realloc there?

OpenStudy (anonymous):

realloc is more elegant.

OpenStudy (anonymous):

why?

Can't find your answer? Make a FREE account and ask your own questions, OR help others and earn volunteer hours!

Join our real-time social learning platform and learn together with your friends!
Can't find your answer? Make a FREE account and ask your own questions, OR help others and earn volunteer hours!

Join our real-time social learning platform and learn together with your friends!