117

I thought by setting the first element to a null would clear the entire contents of a char array.

char my_custom_data[40] = "Hello!";
my_custom_data[0] = '\0';

However, this only sets the first element to null.

or

my_custom_data[0] = 0; 

rather than use memset, I thought the 2 examples above should clear all the data.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
ant2009
  • 27,094
  • 154
  • 411
  • 609

16 Answers16

127

It depends on how you want to view the array. If you are viewing the array as a series of chars, then the only way to clear out the data is to touch every entry. memset is probably the most effective way to achieve this.

On the other hand, if you are choosing to view this as a C/C++ null terminated string, setting the first byte to 0 will effectively clear the string.

dda
  • 6,030
  • 2
  • 25
  • 34
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 4
    They key word in the answer is 'effectively'. Only the first element is begin set to 0 and the rest still have undefined values but if you are treating the array as a null terminated string and the first element is null, then the string is considered empty. – Arnold Spence Mar 11 '09 at 01:46
  • indeed, this is the answer folks. – Johannes Schaub - litb Mar 11 '09 at 01:49
  • @caparcode, exactly. That's why it's very important to understand how the array is being used. – JaredPar Mar 11 '09 at 01:49
  • Yes, that is what I should have said in my first post. The char is a terminated string. so either these will do that trick. char[0] = '\0'; or char[0] = 0. I am not sure but I heard that using '\0' is better for using null terminated strings. – ant2009 Mar 11 '09 at 02:06
  • @robUK, yes you are correct. Technically '\0' is equal to 0 (in ascii) but you should use '\0' because it makes your intention clear – Mark Testa Mar 11 '09 at 02:23
  • About "most effective" - please see http://stackoverflow.com/questions/453432/difference-in-initalizing-and-zeroing-an-array-in-c-c/455137#455137 – Johann Gerell Mar 11 '09 at 07:45
  • you do understand that in ANSI C (atleast) the array[] = {0}; construct only works when you define an array and when you try to do it later on you get a compile error! – hhafez Mar 11 '09 at 23:58
  • Thank you for this answer, it makes more sense to me now. But if the char array is printed using `fprintf` will it print only up to the Null pointer? Or will it print the rest of the junk inside the array? – SSH This Jan 10 '13 at 21:11
  • oh, this is really old... oh well "clear the string" requires more definition here. the c functions that look at strings assume that if they find a '\0' character (null) then that is the end of the string. That's the definition of "null terminated string" oh, this is really old....oh well So if you make the first character of a char array a null character, you have a zero-character (empty) null-terminated string. Whatever else is in the array is irrelevant. – Mister Jeps Dec 20 '22 at 17:30
82

An array in C is just a memory location, so indeed, your my_custom_data[0] = '\0'; assignment simply sets the first element to zero and leaves the other elements intact.

If you want to clear all the elements of the array, you'll have to visit each element. That is what memset is for:

memset(&arr[0], 0, sizeof(arr));

This is generally the fastest way to take care of this. If you can use C++, consider std::fill instead:

char *begin = &arr;
char *end = begin + sizeof(arr);
std::fill(begin, end, 0);
John Feminella
  • 303,634
  • 46
  • 339
  • 357
  • 2
    I believe the second version should be: std::fill( arr, arr+ sizeof(arr)/sizeof(arr[0]), 0 ); – David Rodríguez - dribeas Mar 11 '09 at 00:40
  • Clarification: don't use sizeof with fill because you'll get in trouble later with arrays of int, long, double or what have you. – Zan Lynx Mar 11 '09 at 01:08
  • 1
    I prefer: std::fill(&arr[0], &arr[arr_len], 0); – Zan Lynx Mar 11 '09 at 01:10
  • Zan Lynx, that's undefined behavior. you cannot do &arr[arr_len]. but you have to do std::fill(arr, arr + sizeof arr, 0); or if you have the length somewhere std::fill(arr, arr + arr_len, 0); assuming an array of char – Johannes Schaub - litb Mar 11 '09 at 01:11
  • It is valid only in C . although the question clearly targetted C (another guy added a C++ tag, i've no clue why), the std::fill shows C++ affinity :) – Johannes Schaub - litb Mar 11 '09 at 01:12
  • About "fastest" - http://stackoverflow.com/questions/453432/difference-in-initalizing-and-zeroing-an-array-in-c-c/455137#455137 – Johann Gerell Mar 11 '09 at 07:46
  • @John, you forgot a "&" before arr[0] . Please review the change i made (added it) and decide whether or not to change it to "char *begin = arr;" instead (probably you just forgot to remove the "[0]" ?). wanted to add/remove as least characters as possible :) – Johannes Schaub - litb Mar 11 '09 at 16:07
  • pro tip: use the following macro to get an accurate array size whatever the type may be `#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))` – Someone Somewhere Dec 02 '11 at 18:07
  • and why just not `memset(arr, 0, sizeof(arr));`? – ratojakuf Jan 18 '15 at 14:14
  • ARRAY_SIZE(a) will return the size of the pointer, not the size of the array itself. – Ol Sen Jan 05 '21 at 16:35
27

Why would you think setting a single element would clear the entire array? In C, especially, little ever happens without the programmer explicitly programming it. If you set the first element to zero (or any value), then you have done exactly that, and nothing more.

When initializing you can set an array to zero:

char mcd[40] = {0}; /* sets the whole array */

Otherwise, I don't know any technique other than memset, or something similar.

abelenky
  • 63,815
  • 23
  • 109
  • 159
  • I guess this depends on the compiler you use – cocoafan Mar 11 '11 at 07:38
  • 1
    @cocoafan: No, it is not compiler dependent. It is part of the language specification. Any compiler that behaves differently is not following the C language. – abelenky Mar 12 '11 at 04:26
  • I didn't know that, thank you. I couldn't find any resource where I can read this special case. Would be nice to have it as a bookmark. – cocoafan Mar 13 '11 at 07:58
  • 1
    It is called partial initialization. I don't have the C99 spec, but here are two sources: http://bit.ly/enBC2m "You do not need to initialize all elements in an array. If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type." http://bit.ly/f9asHH "If there are fewer initializers than elements in the array, the remaining elements are automatically initialized to 0" – abelenky Mar 13 '11 at 15:14
  • This does not apply to an array that has already been declared and assigned values does it? – skinnedknuckles Oct 26 '18 at 18:12
12

Use:

memset(my_custom_data, 0, sizeof(my_custom_data));

Or:

memset(my_custom_data, 0, strlen(my_custom_data));
Jake1164
  • 12,291
  • 6
  • 47
  • 64
  • 2
    The second option (`memset(my_custom_data, 0, strlen(my_custom_data));`) will only clear out to the first '\0', which could be beyond the end of the array. This may, or may not, be okay. – brewmanz May 11 '18 at 23:27
  • The first option worked fine on an ESP32, after I tried a lot of other things. – theGtknerd Feb 15 '21 at 19:57
10

Try the following code:

void clean(char *var) {
    int i = 0;
    while(var[i] != '\0') {
        var[i] = '\0';
        i++;
    }
}
Krypton
  • 3,337
  • 5
  • 32
  • 52
7

Why not use memset()? That's how to do it.

Setting the first element leaves the rest of the memory untouched, but str functions will treat the data as empty.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
John Fricker
  • 3,304
  • 21
  • 21
6

Pls find below where I have explained with data in the array after case 1 & case 2.

char sc_ArrData[ 100 ];
strcpy(sc_ArrData,"Hai" );

Case 1:

sc_ArrData[0] = '\0';

Result:

-   "sc_ArrData"
[0] 0 ''
[1] 97 'a'
[2] 105 'i'
[3] 0 ''

Case 2:

memset(&sc_ArrData[0], 0, sizeof(sc_ArrData));

Result:

-   "sc_ArrData"
[0] 0 ''
[1] 0 ''
[2] 0 ''
[3] 0 ''

Though setting first argument to NULL will do the trick, using memset is advisable

Jake1164
  • 12,291
  • 6
  • 47
  • 64
Akaanthan Ccoder
  • 2,159
  • 5
  • 21
  • 37
5

I usually just do like this:

memset(bufferar, '\0', sizeof(bufferar));
Jevgenij Kononov
  • 1,210
  • 16
  • 11
4

Nope. All you are doing is setting the first value to '\0' or 0.

If you are working with null terminated strings, then in the first example, you'll get behavior that mimics what you expect, however the memory is still set.

If you want to clear the memory without using memset, use a for loop.

Alan
  • 45,915
  • 17
  • 113
  • 134
  • I say no on the for loop. Try not to write your own "improved" (and usually not) library functions. In fact, memset and memcpy are rather special are often inlined into custom machine code for the CPU based on what is known about data alignment and length. – Zan Lynx Mar 11 '09 at 01:03
  • @Zan the OP doesn't want to use memset (perhaps he's embedded and doesn't have it available). But yes, memset is usually highly optimal, and likely faster than a for loop. – Adam Hawes Mar 11 '09 at 05:40
  • True, however he didn't want to use memset, so I suggested a for loop. – Alan Mar 11 '09 at 06:44
2

You should use memset. Setting just the first element won't work, you need to set all elements - if not, how could you set only the first element to 0?

Michael
  • 54,279
  • 5
  • 125
  • 144
  • memset shouldn't be used over readability: http://stackoverflow.com/questions/453432/difference-in-initalizing-and-zeroing-an-array-in-c-c/455137#455137 – Johann Gerell Mar 11 '09 at 07:45
2

Writing a null character to the first character does just that. If you treat it as a string, code obeying the null termination character will treat it as a null string, but that is not the same as clearing the data. If you want to actually clear the data you'll need to use memset.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
1

set the first element to NULL. printing the char array will give you nothing back.

1

How about the following:

bzero(my_custom_data,40);
Jake1164
  • 12,291
  • 6
  • 47
  • 64
1

I thought by setting the first element to a null would clear the entire contents of a char array.

That is not correct as you discovered

However, this only sets the first element to null.

Exactly!

You need to use memset to clear all the data, it is not sufficient to set one of the entries to null.

However, if setting an element of the array to null means something special (for example when using a null terminating string in) it might be sufficient to set the first element to null. That way any user of the array will understand that it is empty even though the array still includes the old chars in memory

hhafez
  • 38,949
  • 39
  • 113
  • 143
  • Don't use "memset" over readability: http://stackoverflow.com/questions/453432/difference-in-initalizing-and-zeroing-an-array-in-c-c/455137#455137 – Johann Gerell Mar 11 '09 at 07:47
-3
void clearArray (char *input[]){
    *input = ' '; 
}
wolf
  • 1
  • 1
  • 1
    This is not CLEARING, it is just setting first character to ' '! I think you wanted to write *input = '\0' – sfelber Sep 18 '14 at 13:14
-4

Try the following:

strcpy(my_custom_data,"");
animuson
  • 53,861
  • 28
  • 137
  • 147