powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему такой результат?
24 сообщений из 24, страница 1 из 1
Почему такой результат?
    #38836847
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
const char* md5a(const char* str){
  char str1[10], str2[10];

  strcpy(str1, "Hello");
//  strcpy(str2, str1);

  return &str1;
}

const char* destination = md5a(str);
return (*pEnv)->NewStringUTF(pEnv, destination);




Функция возвращает результат верно: "Hello", но если раскоментировать строку - то возврат "ello".

Почему так???
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836889
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола ПитерскийПочему так???
Потому что ты, видимо, никогда не слышал о времени жизни переменных, указателях и работе
компьютерной памяти. Поэтому используешь указатель на уже несуществующую переменную.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836896
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov, давай без бла-бла - не хочешь помочь так и не надо - или тебе за количество пустых коментов платят?
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836910
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерский,

Нельзя возвращать из функции указатель на локальную переменную. Запрещено.
Перепишите код без возврата такого указателя и все заработает.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836918
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Твой str1[10] после выполнения return превращается в кусок свободной памяти стэка и может быть в любой момент занят другой переменной.
Пиши так:
Код: plaintext
1.
static char str1[10];
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836921
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, дело в том что я понял суть проблемы - но не знаю как это сделать по другому. Мне нужно из функции возвратить строковое значение - как переписать пример чтобы надежно работал? Раньше передавал это значение через пар-р функции - все работало, но теперь хочу переписать на возврат его из функции - или это невозможно?
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836941
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТвой str1[10] после выполнения return превращается в кусок свободной памяти стэка и может быть в любой момент занят другой переменной.
Пиши так:
Код: plaintext
1.
static char str1[10];



Спасибо - теперь работает нормально. А есть ли более правильный способ это делать?

Вот я еще так делаю:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
char* ret='\0'; 
...
if (fid == 0 ) goto END;
...
ret=(char*) malloc(strlen(tmp)+1);
strcpy(ret, tmp );
ret[strlen(ret)] = '\0';

END:
return ret; // const char*



Есть ли в этом примере какие подводные камни?
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836946
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл добавить что со static нельзя два указателя использовать, первый поменяется. Запусти
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
const char* f()
{
  static char ret[10];
  if(ret[0] == 'A') {
	  ret[0] = 'B';
  } else {
	  ret[0] = 'A';
  }
  ret[1] = 0;
  return ret;
}

int main() 
{
	const char* p1 = f();
	puts(p1);
	const char* p2 = f();
	puts(p2);
	puts(p1);
	return 0;
}
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836952
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерский
Код: plaintext
1.
2.
3.
4.
...
ret=(char*) malloc(strlen(tmp)+1);
...
return ret; // const char*



Есть ли в этом примере какие подводные камни?
Надо чтобы потом была освобождена память, когда значение станет ненужно. Т.е. так
Код: plaintext
1.
2.
3.
const char* destination = md5a(str);
...
free(destination);


иначе это утечка памяти.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836959
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, спасибо большое - теперь понял где у меня были косяки:)
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836960
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола ПитерскийА есть ли более правильный способ это делать?
В вызывающем коде создать буфер и передать в параметрах указатель на буфер и его размер.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836967
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВ вызывающем коде создать буфер и передать в параметрах указатель на буфер и его размер.
Микола ПитерскийРаньше передавал это значение через пар-р функции - все работало, но теперь хочу переписать на возврат его из функции
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836975
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола ПитерскийDima TТвой str1[10] после выполнения return превращается в кусок свободной памяти стэка и может быть в любой момент занят другой переменной.
Пиши так:
Код: plaintext
1.
static char str1[10];



Спасибо - теперь работает нормально. А есть ли более правильный способ это делать?

Вот я еще так делаю:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
char* ret='\0'; 
...
if (fid == 0 ) goto END;
...
ret=(char*) malloc(strlen(tmp)+1);
strcpy(ret, tmp );
ret[strlen(ret)] = '\0';

END:
return ret; // const char*



Есть ли в этом примере какие подводные камни?

есть.
пользователь кода должен удалять память.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836978
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ясно - спасибо ребята. Переделаю обратно через параметр - действительно надо в одном месте сосдавать и освобождать память - а то так и до утечки совсем недалеко.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38836993
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола ПитерскийМне нужно из функции возвратить строковое значение - как переписать пример чтобы надежно работал?

Прежде всего, ты должен понять, что в чистом С (в смысле не С++) не может быть просто функции, возвращающей
строковое значение. Функция может только формировать это строковое значение.

Вопрос весь в том, где она будет это делать. Это должно быть определено в спецификации функции.
Она должна использовать какой-то буфер, важно, что это будет за буфер.

Это может быть буфер в статической памяти, но тогда вопрос в размере этого буфера (хватит ли), и в многопоточности.

Это может быть буфер, предоставляемый (с размером) вызвыающей функцией.

Это может быть буфер, выделяемый внутри данной функции.

Это всё должно быть в спецификации на функцию.
После этого можно начинать функцию программировать.

А ты этого не сделал, стал сразу программировать.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38838657
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вариант 1
Код: plaintext
1.
2.
3.
4.
int len = strlen(str);      
char tmp[len + 2 + 1];
strcpy(tmp, str);
strcat(tmp, "14"); 



этот код работает и в конце строки есть "14"

вариант 2
Код: plaintext
1.
2.
3.
4.
5.
6.
int len = strlen(str);      
char tmp[len + 2 + 1];
strcpy(tmp, str);
tmp[len + 1]='1';
tmp[len + 2]='4';
tmp[len + 3]='\0';



этот код в конец строки не добавляет "14" - почему? И как правильно добавить "14", используя вариант №2
...
Рейтинг: 0 / 0
Почему такой результат?
    #38838669
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
strlen() дает количество символов без учета завершающего \0
индекс начинается с нуля, т.е. tmp[len] это '\0' от исходной строки
Так надо
Код: plaintext
1.
2.
3.
tmp[len + 0]='1';
tmp[len + 1]='4';
tmp[len + 2]='\0';
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839774
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решил перевести код на с++ и отгреб кучу проблем - полдня гугления ничего не дали:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
std::string IMEI(JNIEnv* env, jobject pThis, jobject ctx) {
    std::string ret = "";

    jclass contextClass = env->FindClass( "android/content/Context");
    jfieldID fid = env->GetStaticFieldID( contextClass, "TELEPHONY_SERVICE", "Ljava/lang/String;");
    if (fid == 0 ) goto END;

//   jfieldID fid1 = env->GetStaticFieldID( contextClass, "TELEPHONY_SERVICE1", "Ljava/lang/String;");
//   if (fid1 == 0 ) goto END;

    END:
        return ret;
}



Этот код компилируется, но если раскоментировать закомментированные 2 строки - то получаю ошибку:

Код: plaintext
1.
2.
3.
4.
Error:(51, 5) error: jump to label 'END' [-fpermissive]
Error:(17, 25) error: from here [-fpermissive]
Error:(19, 13) error: crosses initialization of '_jfieldID* fid1'


Почему ??????
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839808
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерский,

Там же написано английским по белому: у вас goto перепыгивает через объявление переменной и она некорректно инициализируется.
Объявите jfieldID fid1 и прочие до goto, например в начале функции.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839823
Микола Питерский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, спасибо - действительно помогло. Но этот код без проблем компилируется на С.
И не понятно почему такое ограничение в с++ - или в нем как в делфи теперь все переменные нужно объявлять в начале функции?
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839832
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерский,

В С нет конструкторов, поэтому компиляторы не занимаются выявлением такого кода - хотя и в С и в С++ - это ошибка в программе.
Микола Питерскийтеперь все переменные нужно объявлять в начале функции?
Это относится только к переменным в сочетании с goto и switch.
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839860
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Микола Питерскийэтот код без проблем компилируется на С.
И не понятно почему такое ограничение в с++
А не должен бы компилироваться. Потому что объявление переменных в произвольном блоке это
как раз изобретение С++, а в С они должны были объявляться в начале функции.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839863
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Та ладно, еще в С99 официально разрешили ))
...
Рейтинг: 0 / 0
Почему такой результат?
    #38839905
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovМикола Питерскийэтот код без проблем компилируется на С.
И не понятно почему такое ограничение в с++
А не должен бы компилироваться. Потому что объявление переменных в произвольном блоке это
как раз изобретение С++, а в С они должны были объявляться в начале функции.
]

В С это уже давно "расслабили".
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Почему такой результат?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]