Оптимизиране .......
36 отговора
1429 прегледа
Оптимизиране .......
Искам да попитам възможно ли е следния код да се оптимизира по някакъв начин и да се направи без да се използва буфер, защото ако на входа ми дакажем постъпва много по голям стринг отколкото съм задал за буфер и ще гърми, а пък неща да го правя с str[9000].
Или да се прави с динамично заделяне ?
char *str = "word1 word2 word3";
char *p = str;
char str1[250];
char *n = str1;
while(*p) {
if (isblank(*p)) break;
else *n++ = *p++;
}
*n++ = '\0';
printf("%s",str1);
Just a human.
Или да се прави с динамично заделяне ?
char *str = "word1 word2 word3";
char *p = str;
char str1[250];
char *n = str1;
while(*p) {
if (isblank(*p)) break;
else *n++ = *p++;
}
*n++ = '\0';
printf("%s",str1);
Just a human.
Re: Оптимизиране .......
ако съм те разбрал правилно това би трябвало да върши работа
и да не забравиш да провериш върнатата стойност от calloc !
char str1 = calloc(strlen(str)+1, sizeof(char)) ;
....
...
...
free(str1) ;
и да не забравиш да провериш върнатата стойност от calloc !
Re: Оптимизиране .......
Идеята ми беше да стане с указатели, ама както изглежда ще трябва да се използва динамично заделяне :(
Just a human.
Just a human.
Re: Оптимизиране .......
int i = 0;
while ( !isbalnk( str[ i ] )
i++;
if ( i > 0 )
printf( "%.*s", i, str );
Mostly harmless
while ( !isbalnk( str[ i ] )
i++;
if ( i > 0 )
printf( "%.*s", i, str );
Mostly harmless
Re: Оптимизиране .......
Ми гледай сега, ако го направиш с str[4000] трябва да ти е достатъчно.
Re: Оптимизиране .......
Какъв е смисълът от заделянето на толкова памет ?
ако даречем стринга ми е 10 символа или по - малко ?
Just a human.
ако даречем стринга ми е 10 символа или по - малко ?
Just a human.
леко брутално решение
char *str = "word1 word2 word3";
for(chaр*p = str; *p&&!isblank(*p);p++);
*p=0;
printf("%s",str);
for(chaр*p = str; *p&&!isblank(*p);p++);
*p=0;
printf("%s",str);
не бързай да се радваш
пробва ли го? на доста от операционните системи това нещо ще изгърми при изпълнение, защото константния стринг е защитен. освен това ако имаш няколко константни стринга с еднаква стойност, то всички те се компилират като един, така че дори да не те удари през рацете, то промяната на единия ще промени всички. това нещо е използваемо само ако се ползва за неконстантни стрингове.
Re: не бързай да се радваш
Ако
char *str = "word1 word2 word3";
го сменим на
char str[] = "word1 word2 word3";
Компилатора няма ли да създаде локален ( на стека ) променяем буфер при влизане във функцията? Или вече почвам да забравям езика
?
--
"Agile is a mindset, not a set of practices, rules, or tools."
Tom Poppendieck
char *str = "word1 word2 word3";
го сменим на
char str[] = "word1 word2 word3";
Компилатора няма ли да създаде локален ( на стека ) променяем буфер при влизане във функцията? Или вече почвам да забравям езика
--
"Agile is a mindset, not a set of practices, rules, or tools."
Tom Poppendieck
опа
Пробвах го с gcc на slackware linux:
Като го пусна ми казва следното:
т.е. при двете извиквания на test се използва един и същ буфер. Гадно от една страна - от друга е забавен начин да се застреляш в крака.
Гррр защо като слагам кода в pre блок и ми вкарва допълнителни нови редове
??!
--
"Agile is a mindset, not a set of practices, rules, or tools."
Tom Poppendieck
#include <cstdio>
int test( )
{
char str[] = "bauu muu fuu";
printf( "in test() 0x%x\n", str );
}
int main()
{
char str[] = "bauu muu fuu";
printf( "in main() 0x%x\n", str );
test();
test();
}
Като го пусна ми казва следното:
/home/null/tmp $ ./test
in main() 0xbffffa90
in test() 0xbffffa70
in test() 0xbffffa70
т.е. при двете извиквания на test се използва един и същ буфер. Гадно от една страна - от друга е забавен начин да се застреляш в крака.
Гррр защо като слагам кода в pre блок и ми вкарва допълнителни нови редове
--
"Agile is a mindset, not a set of practices, rules, or tools."
Tom Poppendieck
Re: опа
мноо е вероятно и двата пъти масивът да е на 1 и също място в стека. пробвай да извикаш единия път тест през още една функция.
така че, кракът си е здрав....
да не говорим сега за Джавата там с интърнатите низове колко са забавни...
така че, кракът си е здрав....
да не говорим сега за Джавата там с интърнатите низове колко са забавни...
Редактирано от Questor на
това е гарантирано
със сигурност на всяко влизане от едно ниво локалните променливи са на едно място. а така както той предлага това вече е просто масив натъпкан със константния низ, а не самия константен низ, такла че тука няма проблем.
Re: това е гарантирано
Горе-долу...
Резултат (компилирано с оптимизации):
Резултат (компилирано без оптимизации):
Както се вижда, при компилиране с оптимизации, локалните променливи може и да не са на едно място вече. Сигурно се дължи на inlining.
#include <stdio.h>
int test( )
{
int n;
char str[] = "bauu muu fuu";
char *str1 = "bauu muu fuu";
printf( "in test() 0x%x 0x%x 0x%x\n", str, str1, &n );
}
int main()
{
int n;
char str[] = "bauu muu fuu";
char *str1 = "bauu muu fuu";
printf( "in main() 0x%x 0x%x 0x%x\n", str, str1, &n );
test();
test();
}
Резултат (компилирано с оптимизации):
in main() 0xbffffa30 0x8048638 0xbffffa1c
in test() 0xbffffa20 0x8048638 0xbffffa18
in test() 0xbffffa20 0x8048638 0xbffffa14
Резултат (компилирано без оптимизации):
in main() 0xbffffa30 0x80485d8 0xbffffa4c
in test() 0xbffff9e0 0x80485d8 0xbffff9fc
in test() 0xbffff9e0 0x80485d8 0xbffff9fc
Както се вижда, при компилиране с оптимизации, локалните променливи може и да не са на едно място вече. Сигурно се дължи на inlining.
Re: това е гарантирано
не съм чувал такива гаранции да има.... едно време под вин16 като можеше да ти се премести целия сегмент нанякъде, адресите ша са същите, ама друг път 
хм
отделните нишки нали са със отделен стек? иначе ще се омаца...
та мисълта ми е че не виждам начин как ще се разбута стека, при положение че е само за една нишка. разбира говоря за случай когато се ползват само функции със фиксиран брой параметри
та мисълта ми е че не виждам начин как ще се разбута стека, при положение че е само за една нишка. разбира говоря за случай когато се ползват само функции със фиксиран брой параметри
вай! това пък как става?
да не са забравили някой байт в стека 
?
бах мааму! забележи че адреса на стринга във функцията е по-голям от адреса на n в main! как става тоя номер? бреййй объркаха света тия хора!
бах мааму! забележи че адреса на стринга във функцията е по-голям от адреса на n в main! как става тоя номер? бреййй объркаха света тия хора!
Re: хм
Миии като се замисля, май нищо не пречи да викне първия път test, после ако се смятат някакви изрази примерно да си остави временно някоя и друга дума в стека, после пак да викне test, после да си довърши сметките, и да поп-не думата.
-------
А това за Вин16 - не си спомням със сигурност, ама май можеше и сегмента на стека да се премести?
-------
А това за Вин16 - не си спомням със сигурност, ама май можеше и сегмента на стека да се премести?
Re: вай! това пък как става?
Ми нали ти казвам - компилаторът ги е inline-нал :) И вече нямаме викане на функция, имаме много локални променливи в една функция. А тях как ще ги нареди в стека, само компилаторът си знае.
(компилирал съм с GCC не помня коя версия, с -O3)
P.S. Нали имаше идея навремето да назначим тука освен модератора и един компилатор
Какво ще каже той по въпроса?
(компилирал съм с GCC не помня коя версия, с -O3)
P.S. Нали имаше идея навремето да назначим тука освен модератора и един компилатор