先頭バイトだけfreeするには?

解決


My  2006-10-14 02:50:59  No: 63306  IP: 192.*.*.*

数字の文字列を、char* num=malloc(6);
としてnumにいれているのですが、
numの先頭が"0"のとき、例えば"01234"のとき先頭の"0"を消したいのです。

ですが、num++とすると
free(num)のときにちゃんと開放されてるのかわかりません。

もちろんあらたにメモリをmallocしてコピーするとか、
num++する前にもうひとつ変数を用意しておいて
num2=num;
num++;
処理が終わったら、
free(num2);
とすればいいのですが・・・  
reallocみたいな先頭のバイトだけ開放する関数ってあるのでしょうか?
もしご存知でしたら教えてください。よろしくお願いいたします。

編集 削除
Blue  2006-10-14 08:35:11  No: 63307  IP: 192.*.*.*

> reallocみたいな先頭のバイトだけ開放する関数ってあるのでしょうか?
ないとおもう。

というか、freeにはmallocが返した値を指定しないといけないから、
>ですが、num++とすると
>free(num)のときにちゃんと開放されてるのかわかりません。
は間違いです。

やはり普通に別領域を用意してコピーするしかないでしょう。

char* buff = malloc( strlen( num ) );
strcpy( buff, num + 1 );
free( num );
num = buff;

それか、単に値をずらすだけでもいいと思うんだけど。
(普通はそうするとおもう。)

memmov( num, num + 1, strlen( num ) );

編集 削除
Blue  2006-10-14 08:58:39  No: 63308  IP: 192.*.*.*

訂正)
>memmov
memmove

編集 削除
瀬戸っぷ  2006-10-14 12:17:00  No: 63309  IP: 192.*.*.*

>memmove( num, num + 1, strlen( num ) );

文字列ならば、strlen(num)+1として'\0'分のコピー(移動)も実施した方が。

編集 削除
Blue  2006-10-14 15:45:04  No: 63310  IP: 192.*.*.*

> 文字列ならば、strlen(num)+1として'\0'分のコピー(移動)も実施した方が。
num ならば strlen( num ) + 1 で 文字数 + '\0'の文字数 ですが、
num + 1 ですので strlen( num ) で ( 文字数 - 1 ) + '\0'の文字数
となります。

つまり、strlen( num ) + 1 だと、'\0' の次の領域を参照してしまうのでNGです。

編集 削除
My  2006-10-14 18:43:45  No: 63311  IP: 192.*.*.*

>Blue様  瀬戸っぷ様
レスありがとうございます。

>> reallocみたいな先頭のバイトだけ開放する関数ってあるのでしょうか?
>ないとおもう。
がーん

>それか、単に値をずらすだけでもいいと思うんだけど。
>(普通はそうするとおもう。)
実は大きな数字の計算プログラムを作っているのですが、新たにmallocすると遅そうだからmallocしたり、データの移動を行いたくないのです。
reallocで後ろのバイトを削るときは、新たにmallocしたり、データの移動はしてないですよね??
memmove(num,num+1,strlen(num))の場合
for(long i=0;i<strlen(num);i++){
     num[i]=num[i+1];
}
という処理をしてしまいますよね?
だから特定の部分のメモリを開放できるといいんですが・・・
無理なんでしょうか??

編集 削除
Ban  2006-10-14 19:03:00  No: 63312  IP: 192.*.*.*

> 無理なんでしょうか??

alloc系では無理です。

常に先頭を削るだけならstd::dequeなんてのもアリかも。
>先頭と末尾の削除が高速な、インデクス参照できるSTLコンテナ。

編集 削除
Ban  2006-10-14 19:04:31  No: 63313  IP: 192.*.*.*

あ、先頭詰めなんてしないで先頭インデクスを別に持つとか、
そもそものアルゴリズムを見直すとか、
根本の対策を考えた方がいいきはしますが、今の前提なら。

編集 削除
My  2006-10-14 19:51:24  No: 63314  IP: 192.*.*.*

>Ban様

レスありがとうございます。
やっぱりCではうまい関数ないんですね・・・
std::dequeってC++??

>あ、先頭詰めなんてしないで先頭インデクスを別に持つとか、
とりあえずそうします。
お手数おかけしまして申し訳ありませんでした。

編集 削除
Ban  2006-10-14 20:47:21  No: 63315  IP: 192.*.*.*

> std::dequeってC++??

そうです。
Standard Template Library(STL)と呼ばれるC++の標準ライブラリにある、
コンテナの一種です。

C++だと、リンクリストとかツリーとか動的配列とか、基本データ構造は標準提供です。
で、これらに対するアルゴリズム(部分ソートとか検索とかもろもろ)も結構使える
レベルで標準提供されます。(対象データ型はtemplate使うので変更可能)

編集 削除
yoh2  2006-10-14 21:07:10  No: 63316  IP: 192.*.*.*

本題とは関係ありませんが。

> reallocで後ろのバイトを削るときは、新たにmallocしたり、データの移動はしてないですよね??

規格を見る限りそういった保証はありません。
それどころか、バイト数が減る or 変わらない時に必ず成功するといった保証すらありません。
VC++ 2005 Express のリファレンスも見てみましたが、こちらも同様でした。

編集 削除
My  2006-10-14 22:05:24  No: 63317  IP: 192.*.*.*

>Ban様

丁寧に教えていただいて感謝です。C++って便利そうですね。
ありがとうございました。

>yoh2様
>> reallocで後ろのバイトを削るときは、新たにmallocしたり、データの移動はして>ないですよね??

ごめんなさい、想像してこう書きました。調べていただいて頭が下がります。
とりあえず解決にしておきます。

編集 削除
瀬戸っぷ  2006-10-14 23:31:51  No: 63318  IP: 192.*.*.*

> つまり、strlen( num ) + 1 だと、'\0' の次の領域を参照してしまうのでNGです。

そうでした。
アホなコト書いて申し訳ない。

編集 削除