Re[4]: char*
От: Centaur Россия  
Дата: 05.04.05 15:22
Оценка: 14 (3) +1
Здравствуйте, SergeyL, Вы писали:

SL>
SL>BOOL IsBadReadPtr(
SL>  CONST VOID *lp,  // memory address
SL>  UINT_PTR ucb     // size of block
SL>);
SL>


Larry Osterman’s Weblog, Confessions of an Old Fogey: Should I check the parameters to my function?

The way you check for bad pointers on Win32 is by calling the IsBadReadPtr and IsBadWritePtr API. Michael Howard calls these APIs “CrashMyApplication” and “CorruptMemoryAndCrashMySystem” respectively. The problem with IsBadReadPtr/IsBadWritePtr is that they do exactly what they’re advertised as doing: They read and/or write to the memory location specified, with an exception handler wrapped around the read/write. If an exception is thrown, they fail, if not, they succeed.

There are two problems with this. The only thing that IsBadReadPtr/IsBadWritePtr verifies is that at the instant that the API is called, there was valid memory at that location. There’s nothing to prevent another thread in the application from unmapping the virtual address passed into IsBadReadPtr immediately after the call is made. Which means that any error checks you made based on the results of this API aren’t valid (this is called out in the documentation for IsBadWritePtr/IsBadReadPtr).

The other one is worse. What happens if the memory address passed into IsBadReadPtr is a stack guard page (a guard page is a page kept at the bottom of the stack – when the system top level exception handler sees a fault on a guard page, it will grow the threads stack (up to the threads stack limit))? Well, the IsBadReadPtr will catch the guard page exception and will handle it (because IsBadReadPtr handles all exceptions). So the system exception handler doesn’t see the exception. Which means that when that thread later runs, its stack won’t grow past the current limit. By calling IsBadReadPtr in your API, you’ve turned an easily identifiable application bug into a really subtle stack overflow bug that may not be encountered for many minutes (or hours) later.

Re: char*
От: ssm Россия  
Дата: 04.04.05 10:53
Оценка: 12 (1)
Здравствуйте, Pavel Dvorkin, Вы писали:



PD>Свое решение не привожу, интересно, кто что скажет.


такой вопрос, а возможно на паскале сделать функцию StrCmp которую экспортировать, для дальнейшего использования в C? тогда отпадет вообще надобность о знании внутреннем устройстве стороки Фортрана...
char*
От: Pavel Dvorkin Россия  
Дата: 04.04.05 10:42
Оценка:
Уважаемый Олл!

Проблема банальна, решения точного не существует. Меня интересует, кто что думает о лучшем решении.

В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно. Она не может внутри себя иметь пробелов и может их иметь в конце (но может не иметь). Если пробелы в конце есть — первый из них рассматривается как конец строки.

Эту строку надо сравнить с массивом других и найти равную.

Ясно, что точного решения нет, но что лучше всего сделать ?

Изменения в строке делать нельзя (например) искать пробел и встроить на его место ноль), так как строка может храниться на странице read-only. Копировать можно, но опять-таки где ее конец — сказать трудно.

Свое решение не привожу, интересно, кто что скажет.
With best regards
Pavel Dvorkin
Re: char*
От: rus blood Россия  
Дата: 04.04.05 10:52
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

Передать вместе со строкой ее длину, конечно, нельзя?
Имею скафандр — готов путешествовать!
Re: char*
От: SergeyL Россия  
Дата: 04.04.05 10:54
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Уважаемый Олл!


PD>Проблема банальна, решения точного не существует. Меня интересует, кто что думает о лучшем решении.


PD>В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно. Она не может внутри себя иметь пробелов и может их иметь в конце (но может не иметь). Если пробелы в конце есть — первый из них рассматривается как конец строки.


PD>Эту строку надо сравнить с массивом других и найти равную.


PD>Ясно, что точного решения нет, но что лучше всего сделать ?


PD>Изменения в строке делать нельзя (например) искать пробел и встроить на его место ноль), так как строка может храниться на странице read-only. Копировать можно, но опять-таки где ее конец — сказать трудно.


PD>Свое решение не привожу, интересно, кто что скажет.



//попробуем угадать максимальный размер строки

char stringCopy[MAX_STRING_SIZE];

//в принципе, здесь можно сначала проверить имею-ли я доступ к этому куску памяти...

memcpy(&stringCopy[0],srcString,MAX_STRING_SIZE-1);

stringCopy[MAX_STRING_SIZE-1] = 0;

// а потом еще проверяем на пробелы, ну и т.д.
Re: char*
От: korzhik Россия  
Дата: 04.04.05 10:54
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно. Она не может внутри себя иметь пробелов и может их иметь в конце (но может не иметь). Если пробелы в конце есть — первый из них рассматривается как конец строки.


PD>Эту строку надо сравнить с массивом других и найти равную.

PD>Ясно, что точного решения нет, но что лучше всего сделать ?

PD>Изменения в строке делать нельзя (например) искать пробел и встроить на его место ноль), так как строка может храниться на странице read-only. Копировать можно, но опять-таки где ее конец — сказать трудно.


А изменить код можно? Чтобы он передавал в C — функцию char* и длину строки?
Re[2]: char*
От: ssm Россия  
Дата: 04.04.05 10:57
Оценка:
Здравствуйте, ssm, Вы писали:


ssm>...а возможно на Фортране сделать функцию StrCmp...
Re: char*
От: zuv  
Дата: 04.04.05 11:02
Оценка:
PD>Эту строку надо сравнить с массивом других и найти равную.

PD>Ясно, что точного решения нет, но что лучше всего сделать ?


Первое, что приходит в голову — нужно определить длину строки, например, поискать закономерности в символах поступающих в строку. Если брать сам алгоритм, то производить проверки до первого пробела или до первого некорректного символа, или до первого нуля, или до завершения известной строки. Получится от нуля до n строк. Если n, то наверное включить генератор случайных чисел .
Re[2]: char*
От: Privalov  
Дата: 04.04.05 11:04
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>такой вопрос, а возможно на паскале сделать функцию StrCmp которую экспортировать, для дальнейшего использования в C? тогда отпадет вообще надобность о знании внутреннем устройстве стороки Фортрана...


Когда-то давно смотрел, как устроены строки в MS Fortran 5.0. Компилятор брал константу из объявления строки и везде в дальнейшем подставлял непосредственное значение. Я, когда подобное делал, знал, как объявлены строки в Фортране, поэтому такой проблемы у меня не возникало. Если был доступен исходник Фортран-программы, объявлял строку как С-строку, тогда к ней добавлялся 0 в конце. Правда, я и сейчас не знаю, вошло ли это в стандарт Фортрана.
AFAIK, в строках Паскаля длина хранится в начале строки. И потом, использовать еще один язык, imho, лишнее.
Re: char*
От: Аноним  
Дата: 04.04.05 11:06
Оценка:
PD>В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно.

А разве в Фортране строки заканчиваются не на '$' ?
Re[3]: char*
От: ssm Россия  
Дата: 04.04.05 11:10
Оценка:
Здравствуйте, Privalov, Вы писали:


P>AFAIK, в строках Паскаля длина хранится в начале строки. И потом, использовать еще один язык, imho, лишнее.


это была описка по поводу паскаля, я имел в виду Фортран
Re: char*
От: MaximE Великобритания  
Дата: 04.04.05 12:21
Оценка:
Pavel Dvorkin wrote:

> В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно. Она не может внутри себя иметь пробелов и может их иметь в конце (но может не иметь). Если пробелы в конце есть — первый из них рассматривается как конец строки.


А если нет пробелов в конце? Как гарантированно определить конец строки?

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: char*
От: Privalov  
Дата: 04.04.05 12:28
Оценка:
Здравствуйте, ssm, Вы писали:


ssm>это была описка по поводу паскаля, я имел в виду Фортран


Да, я увидел твою поправку после того, как отправил свой пост. В Фортране, AFAIR, есть функция LEN, возвращающая длину строки. Проблема в том, что возвращает она объявленную, а не фактическую длину. Откровенно говоря, не помню, что происходит при перезаписи в строку, мусор с прошлого раза, imho, не остается. Как-нибудь этим воспользоваться. Но максимальную длину знать не помешает.
Re: char*
От: Аноним  
Дата: 04.04.05 12:37
Оценка:
менять надо....

Одно можно сказать уверенно.
Осторожнее с этой "библиотекой" на фортране, если уж такая оплошность вылезла тогда сложно даже догадаться что там еще есть.


Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Уважаемый Олл!


PD>Проблема банальна, решения точного не существует. Меня интересует, кто что думает о лучшем решении.


PD>В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно. Она не может внутри себя иметь пробелов и может их иметь в конце (но может не иметь). Если пробелы в конце есть — первый из них рассматривается как конец строки.


PD>Эту строку надо сравнить с массивом других и найти равную.


PD>Ясно, что точного решения нет, но что лучше всего сделать ?


PD>Изменения в строке делать нельзя (например) искать пробел и встроить на его место ноль), так как строка может храниться на странице read-only. Копировать можно, но опять-таки где ее конец — сказать трудно.


PD>Свое решение не привожу, интересно, кто что скажет.
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:16
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, Pavel Dvorkin, Вы писали:


RB>Передать вместе со строкой ее длину, конечно, нельзя?


Хе-хе... Иногда она передается сама, хоть я и не просил — если пытаюсь возвращать из C функции строку. В этом случае возвращаемая строка в С функции оказывается в виде двух ВХОДНЫХ параметров — строка и длина. Я сегодня соорудил такую функцию, у нее в С 4 аргумента, а в Фортране — 2

А в обычном случае — не передается. И передать сам не могу, т.к. не знаю, а знал бы — не хочу.
With best regards
Pavel Dvorkin
Re[3]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:19
Оценка:
Здравствуйте, Privalov, Вы писали:

P>Здравствуйте, ssm, Вы писали:


P>Когда-то давно смотрел, как устроены строки в MS Fortran 5.0. Компилятор брал константу из объявления строки и везде в дальнейшем подставлял непосредственное значение. Я, когда подобное делал, знал, как объявлены строки в Фортране, поэтому такой проблемы у меня не возникало. Если был доступен исходник Фортран-программы, объявлял строку как С-строку, тогда к ней добавлялся 0 в конце. Правда, я и сейчас не знаю, вошло ли это в стандарт Фортрана.


Да, это я и делаю. Но вдруг юзер забудет добавить C в конце...
With best regards
Pavel Dvorkin
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:21
Оценка:
Здравствуйте, SergeyL, Вы писали:


SL>char stringCopy[MAX_STRING_SIZE];


SL>//в принципе, здесь можно сначала проверить имею-ли я доступ к этому куску памяти...


SL>memcpy(&stringCopy[0],srcString,MAX_STRING_SIZE-1);


Здесь и на AV недолго нарваться... Откуда ты знаешь, что из srcString можно копировать MAX_STRING_SIZE-1 ?
With best regards
Pavel Dvorkin
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:24
Оценка:
Здравствуйте, korzhik, Вы писали:


K>А изменить код можно? Чтобы он передавал в C — функцию char* и длину строки?


В Форране есть строки с нулем

CHARACTER*10 STR

STR= 'ABC'C

Но пользователь может C забыть

Изменять ее в Фортране нельзя — не могу я требовать от пользователя, чтобы он каждую строку в специальную функцию передавал

CALL SUB('TEST STRING'C)

имеет право и будет нормально

CALL SUB('TEST STRING)

может привести к проблеме
With best regards
Pavel Dvorkin
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:25
Оценка:
Здравствуйте, zuv, Вы писали:


zuv>Первое, что приходит в голову — нужно определить длину строки, например, поискать закономерности в символах поступающих в строку. Если брать сам алгоритм, то производить проверки до первого пробела или до первого некорректного символа, или до первого нуля,


Или это кончится AV.
With best regards
Pavel Dvorkin
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:25
Оценка:
Здравствуйте, Аноним, Вы писали:

PD>>В функцию передается указатель char*. Он показывает на строку, но она может быть не закончена нулем. Ничего не поделаешь — строка передается из Фортрана, там это не обязательно.


А>А разве в Фортране строки заканчиваются не на '$' ?


Это в Бейсике ИМЕНА текстовых переменных заканчиваются $
With best regards
Pavel Dvorkin
Re[2]: char*
От: Pavel Dvorkin Россия  
Дата: 05.04.05 10:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>менять надо....


что или кого ?

А>Одно можно сказать уверенно.

А>Осторожнее с этой "библиотекой" на фортране, если уж такая оплошность вылезла тогда сложно даже догадаться что там еще есть.

Осторожно — не разговор, мне сделать надо.
With best regards
Pavel Dvorkin
Re[3]: char*
От: korzhik Россия  
Дата: 05.04.05 10:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В Форране есть строки с нулем

PD>CHARACTER*10 STR
PD>STR= 'ABC'C
PD>Но пользователь может C забыть
PD>Изменять ее в Фортране нельзя — не могу я требовать от пользователя, чтобы он каждую строку в специальную функцию передавал
PD>CALL SUB('TEST STRING'C)
PD>имеет право и будет нормально
PD>CALL SUB('TEST STRING)
PD>может привести к проблеме

Насколько я знаю, в Фортране, когда передаёшь строку в функцию, как последний скрытый параметр передаётся максимальная длина этой строки. То есть, если мы делаем интерфейс между Фортран и C мы должны сишную функцию принимающую фортрановскую строку объявлять так:
  void SUB(char*, unsigned)

иначе не скомпилится. правильно я понимаю?

А вот что будет при CALL SUB('TEST STRING'C), будет ли скрытый параметр?
Re[3]: char*
От: SergeyL Россия  
Дата: 05.04.05 10:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, SergeyL, Вы писали:



SL>>char stringCopy[MAX_STRING_SIZE];


SL>>//в принципе, здесь можно сначала проверить имею-ли я доступ к этому куску памяти...


SL>>memcpy(&stringCopy[0],srcString,MAX_STRING_SIZE-1);


PD>Здесь и на AV недолго нарваться... Откуда ты знаешь, что из srcString можно копировать MAX_STRING_SIZE-1 ?



//в принципе, здесь можно сначала проверить имею-ли я доступ к этому куску памяти...

BOOL IsBadReadPtr(
  CONST VOID *lp,  // memory address
  UINT_PTR ucb     // size of block
);
Re[3]: char*
От: Privalov  
Дата: 05.04.05 10:54
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, korzhik, Вы писали:



K>>А изменить код можно? Чтобы он передавал в C — функцию char* и длину строки?


PD>В Форране есть строки с нулем


PD>CHARACTER*10 STR


PD>STR= 'ABC'C


PD>Но пользователь может C забыть


А разве нельзя объявить так:
    CHARACTER*10 STR[C]

Если я правильно вспомнил...
Re[4]: char*
От: Pavel Dvorkin Россия  
Дата: 06.04.05 07:53
Оценка:
Здравствуйте, korzhik, Вы писали:


K>Насколько я знаю, в Фортране, когда передаёшь строку в функцию, как последний скрытый параметр передаётся максимальная длина этой строки. То есть, если мы делаем интерфейс между Фортран и C мы должны сишную функцию принимающую фортрановскую строку объявлять так:

K>
K>  void SUB(char*, unsigned)
K>

K>иначе не скомпилится. правильно я понимаю?

Скомпилируется что угодно, работать не будет.
Если в фортране функция описана как имеющая С интерфейс, это не делается.
With best regards
Pavel Dvorkin
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.